Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > С/С++
Перезагрузить страницу Шаблонные классы-друзья как с ними работать
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
suro suro вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 24.03.2011
По умолчанию Шаблонные классы-друзья как с ними работать - 24.03.2011, 15:06

Есть некий шаблонный класс myClass1 и еще один myClass2 с элементом, типа myClass1. Надо myClass2 сделать другом классу myClass1, и при этом учесть тип.

Блин, перечитал несколько раз - сам с трудом понял, но как лучше написать - не знаю, вот объясняющий пример - friends.h:
cpp Код:
#ifndef _FRIENDS_H_
#define _FRIENDS_H_

template<class TYPE> class myClass1
{
····friend class myClass2<TYPE>;
};

template<class TYPE> class myClass2
{
····public:
········myClass2() {}
········~myClass2() {}
····private:
········myClass1<TYPE> *somePtr;
};

#endif

при компиляции получаем ошибку:
bash Код:
$ g++ friends.h -c
friends.h:6: error: 'myClass2' is not a template
$

С одной стороны оно логично - ведь компилятор читает сверху вниз, и в момент объявления myClass2 другом - он еще не добрался до описания этого класса. С другой стороны - выше myClass2 не поставишь, будет ругаться на
cpp Код:
myClass1<TYPE> *somePtr;
.

Подскажите - как в таком случае быть?
Ответить с цитированием
  (#2 (permalink)) Старый
Влад Влад вне форума
Специалист
 
Сообщений: 3,884
Сказал(а) спасибо: 1
Поблагодарили 25 раз(а) в 25 сообщениях
Регистрация: 27.06.2002
Адрес: Санкт-Петербург
По умолчанию 24.03.2011, 15:24

cpp Код:
#ifndef _FRIENDS_H_
#define _FRIENDS_H_

template<class TYPE> class myClass1
{
    template <typename T> friend class myClass2;
};

template<class TYPE> class myClass2
{
public:
    myClass2() {};
    ~myClass2() {};
private:
    myClass1<TYPE> *somePtr;
};

#endif


The difference between theory and practice is that in theory, there is no difference between theory and practice, but in practice, there is.
Ответить с цитированием
  (#3 (permalink)) Старый
suro suro вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 24.03.2011
По умолчанию 24.03.2011, 15:36

не помогает, все тоже самое:
bash Код:
$  grep typename friends.h && g++ friends.h -c
        template <typename T> friend class myClass2<TYPE>;
friends.h:6: error: 'myClass2' is not a template
$

Вариации на тему T<->TYPE class<->typename тоже не выручили
Ответить с цитированием
  (#4 (permalink)) Старый
Влад Влад вне форума
Специалист
 
Сообщений: 3,884
Сказал(а) спасибо: 1
Поблагодарили 25 раз(а) в 25 сообщениях
Регистрация: 27.06.2002
Адрес: Санкт-Петербург
По умолчанию 24.03.2011, 15:52

Воспользуйся copy-n-paste. Обрати внимание на разницу в коде:
твой код : template <typename T> friend class myClass2<TYPE>;
мой код : template <typename T> friend class myClass2;
GCC 4.6 кушает его без единого ругательства.


The difference between theory and practice is that in theory, there is no difference between theory and practice, but in practice, there is.
Ответить с цитированием
  (#5 (permalink)) Старый
suro suro вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 24.03.2011
По умолчанию 24.03.2011, 16:42

да, извиняюсь, заметил. Действительно компилится.
Пытаюсь понять - а будет ли в таком случае экземпляр myClass2<float> дружить с экземпляром myClass1<int>? Потому что в справочниках прямого ответа найти что-то не могу.

Пишут только про старый стандарт, где typename еще не было.
правда может не там ищу...
Ответить с цитированием
Ads.
  (#6 (permalink)) Старый
suro suro вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 24.03.2011
По умолчанию 24.03.2011, 17:32

Нет, получается не совсем то, что мне нужно.
Попытка компиляции такого кода:
cpp Код:
#include <iostream>

using namespace std;

template<class TYPE> class myClass1
{
····template<typename T>friend class myClass2;

····public:
········myClass1(TYPE data) { value = data; }
········~myClass1() {}

····private:
········TYPE value;
};

template<class TYPE> class myClass2
{

····public:
········myClass2(TYPE data) { value = data; }
········~myClass2() {}
········void showFriendValue(myClass1<TYPE> &);

····private:
········myClass1<TYPE> *somePtr;
········TYPE value;
};

template<class TYPE> void myClass2<TYPE>::showFriendValue(myClass1<TYPE> &c) { cout << c.value << endl; }

int main() {
····const char *a = "a";

····myClass1<const char*> c1(a);
//··myClass1<int> c1(2);
//··myClass2<const char*> c2(a);
····myClass2<int> c2(1);
····c2.showFriendValue(c1);
}
Ругается на отсутствие подходящей функции.
bash Код:
$ g++ friends.cpp -o friends
friends.cpp: In function 'int main()':
friends.cpp:39: error: no matching function for call to 'myClass2<int>::showFriendValue(myClass1<const char*>&)'
friends.cpp:30: note: candidates are: void myClass2<TYPE>::showFriendValue(myClass1<TYPE>&) [with TYPE = int]
$

А хотелось бы увидеть:
что-то вроде:
bash Код:
error: 'const char* myClass2<TYPE>::value ' is private
Ответить с цитированием
  (#7 (permalink)) Старый
<name> <name> вне форума
Новичок
 
Сообщений: 11
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 23.01.2011
По умолчанию 25.03.2011, 03:35

В вашем случае классу myClass2 дружественен шаблон класса myClass1. Это значит, что myClass2 дружественен всем спецификациям шаблона, в т.ч. myClass1<const char*> и myClass1<int>. Поэтому ошибки, которой вы хотели не возникнет. С другой стороны, определение функции showFriendValue требует, чтобы в ее параметре была указана спецификация класса с типом TYPE таким же, как и у myClass2. То есть компилятор ругается на то, что он не может найти метод
cpp Код:
void myClass2<int>::showFriendValue(myClass1<const char*>&);
Чтобы это допускалось необходимо объявить метод как
cpp Код:
template <class T2> void showFriendValue(myClass1<T2> &);
и определить как
cpp Код:
template<class TYPE> template <class T2> void myClass2<TYPE>::showFriendValue(myClass1<T2> &c){}
Если же вам необходима дружественность класса myClass1<TYPE> только конкретной спецификации шаблона, например myClass2<TYPE>, то классы следовало определять как
cpp Код:
template<typename T> class myClass2;

template<class TYPE> class myClass1
{
    friend class myClass2<TYPE>;
    //...
};

template<class TYPE> class myClass2
{
};
Ответить с цитированием
  (#8 (permalink)) Старый
suro suro вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 24.03.2011
По умолчанию 25.03.2011, 09:57

спасибо за развернутый, обстоятельный ответ.
Ответить с цитированием
Ads
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Шаблонные алгоритмы в С++ используя функцию sort zhekha Visual C++ 10 19.11.2008 23:53
С++ списки как с ними работать imported_madjihad С/С++ 6 21.05.2008 16:58
Кодировки как с ними работать imported_Devil Windows CE 1 25.04.2007 12:51
Указатели как с ними работать Гоблин Java 4 21.03.2007 17:25
Классы из DLL почему перестают работать функции andr484 C++ Builder 13 01.09.2006 05:07
Классы как с ними работать Klose Delphi 7 31.05.2006 17:45
C++ и SCO как с ними работать c++ Мысли вслух 6 28.01.2006 07:50
Что такое классы и как с ними работать romannbo Вопросы начинающих программистов 1 21.04.2005 01:37
Классы в DLL и работа с ними AntiGamer Visual C++ 10 08.03.2005 22:44
Classes как с ними работать Partyzan Java 1 16.03.2004 00:16
Классы как с ними работать Anonymous Pascal 2 30.11.2003 19:32
IIS и ASP как с ними работать Anonymous ASP 2 04.04.2003 18:24



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов