Friend - класс шаблон

AlexRyzhenko

Подскажите, пожалуйста, почему Visual C++ 2010 Express нормально компилирует код
template <class NODETYPE> class QueueNode
{
       ...
       template <class NODETYPE> friend class Queue;
};
template <class NODETYPE> class Queue
{
     ...
}
а MinGw версии 5,1,6 и последней версии - нет. Как-то неправильно объявляю друга? А как правильно?
14 ответов

AlexRyzhenko

AlexRyzhenko, Определитть класс Queue заранее. Неполное объявление класса.


AlexRyzhenko

ForEveR, можно подробней?


AlexRyzhenko

Но вообще как-то не логично. Зачем узел очереди - друг очереди?) Разве это не ее составная часть?)
template <class NODETYPE> class Queue;
 
template <class NODETYPE> class QueueNode
{
       ...
       template <class NODETYPE> friend class Queue;
};
template <class NODETYPE> class Queue
{
     ...
};


AlexRyzhenko

ForEveR, так как Вы предлогаете не компилится. Компилится только если написать так
friend class Queue <NODETYPE>;
Кстати, в примере у Дейтелов так и есть. Ну, в принципе это ладно, если всё написано правильно и в vs компилится, хотя нужно разобраться почему. Что касается того, почему дружественная - делаю как в примере, хотя, наверно, стоит элемент сделать частью... Спасибо.Теперь я не пойму как обращаться к классу QueueNode. Если, например, метод класса Queue возвращает указатель на объект класса QueueNode, то что писать в объявлении и в определении метода?


AlexRyzhenko

Поддерживаю ForEveRа, например, такая структура очереди была бы логичнее:
template< typename T >
struct Node
{
    T _data;
    Node *_next;
 
    Node(T data): _data(data), _next(0) { }
};
 
template< typename T >
class Queue
{
public:
    Queue(): _first(0), _last(0) { }
    
    bool is_empty() { return _first == 0; }
 
    void push(T);
    T pop() const;
 
private:
    Node *_first;
    Node *_last;
};


AlexRyzhenko

silent_1991, я не понял чем моя отличается от Вашей, кроме того, что один элемент у Вас не как класс, а как структура.


AlexRyzhenko

AlexRyzhenko, ну, вашу очередь я не видел. Но у меня нет никаких друзей. Почему узел - это друг очереди? Это как вагон - друг поезда. Т.е. абсурдно. Друг нужен, чтобы один класс (в случае классов-друзей) имел доступ к закрытым элементам своего друга. Только вот зачем узлу иметь доступ к элементам обёртки? Узлу надо выполнять свою основную функцию - хранить данные и помнить о своём соседе (или соседях). У него даже никаких методов быть не должно - ему выполнять нечего.А, всё, понял. У вас наоборот, обёртка - друг узла. Да, тогда разницы нет, у меня просто все данные изначально открыты, поскольку узел - структура.


AlexRyzhenko

Я ввёл класс QueueNode в класс Queue. Если отказаться от функции возвращающей указатель, то в vs нормально, а MinGW пишет: template.h:4:14: error: declaration of 'class NODETYPE' template.h:2:11: error: shadows template parm 'class NODETYPE' Посмотрите, пожалуйста, исходники.


AlexRyzhenko

У вас типы в шаблонах повторяются. Во вложенном классе опишите тип как _NODETYPE, ну или вообще другим именем.


AlexRyzhenko

silent_1991, да так нормально. Спасибо. Мне ещё интересно, как определить конструктор за пределами класса? В чём там фишка?


AlexRyzhenko

Как и любую другую функцию - через оператор разрешения области действия ::
class foo
{
public:
    foo(int = 0);
 
private:
    int _a;
};
 
foo::foo(int a):
_a(a)
{
}


AlexRyzhenko

Нет. Конструктор класса QueueNode.


AlexRyzhenko

AlexRyzhenko, а у него что, какие-то особенности есть, которых в других конструкторах нету?
class foo
{
    class bar
    {
    public:
        bar(int = 0);
 
    private:
        int _b;
    };
};
 
foo::bar::bar(int b):
_b(b)
{
}


AlexRyzhenko

Что я запутался с параметрами. Конструктор определить не получается. В примере легче. Вот что я пищу:
template <class NOPDETYPE> Queue<NODETYPE>::QueueNode<_NODETYPE>::QueueNode(const _NODETYPE info)
{
}
И vs подчёркивает всю внутренность и ощибки пишет