首页 > 解决方案 > Why is T undefined? I am trying to implement a node class to use for a doubly linkedlist and it does not like the T after I use the friend operator

问题描述

class Node{
    template<class T>
    friend class DLList; 
    private:
    T data;
    Node* next;
    Node* prev;
    public:

    Node():next(nullptr),prev(nullptr){}
    Node(T val):next(nullptr),prev(nullptr),data(val){}
    Node(const Node<T>& rhs):next(nullptr),prev(nullptr),data(rhs.data){}
    ~Node();
};

I keep getting the T is an unknown type someone please explain to me why.

标签: c++

解决方案


class Node{
    template<class T>
    friend class DLList; 

唯一被模板化的是朋友。Node没有模板化。

解决方案:将 Node 也设为模板

template<class T>
class DLList; // declare DLList is a template so that it's a template when friended

template<class T>
class Node{

    friend class DLList<T>; // Node is now a friend of DLList<T> and no other DLLists 
private:
    T data;
    Node* next;
    Node* prev;
public:

    Node():next(nullptr),prev(nullptr){} // I don't recommend having this constructor.
                                         // If T doesn't have a default constructor, 
                                         // the program will not compile and the error 
                                         // messages can be quite inscrutable.
    Node(T val):data(val), next(nullptr),prev(nullptr){}
                                         // I moved data to the front of the line because 
                                         // the members are always initialized in the 
                                         // same order as they are defined no matter the 
                                         // order they are in in the initializer list. It 
                                         // doesn't matter here, but I see it as a 
                                         // sanitation issue.
    Node(const Node<T>& rhs):data(rhs.val), next(nullptr),prev(nullptr){}
                                         // corrected this constructor to use the correct 
                                         // input value. I don't recommend having this 
                                         // constructor. 1) You Probably don't need it. 
                                         // the default constructor should be good enough
                                         // and 2) this isn't really a copy. 
    ~Node();
};

template<class T>
class DLList // now we define DLList for real.
{

};

但是...有更好的方法来做到这一点。

我们可以使类Node的私有成员DLList。现在只能DLList看到Nodes,我们可以让所有的Node成员public

template<class T>
class DLList
{
private:
    class Node{
    public:
        T data;
        Node* next;
        Node* prev;

        Node(const T & val):data(val), next(nullptr),prev(nullptr){}
        Node(const T & val,  Node* p, Node* n):data(val), next(p), prev(n){}
                                         // Having a constructor that sets the prev and 
                                         // next pointers makes insertion logic just a 
                                         // bit easier later.
        ~Node();
    };

    // private DLList stuff goes here
public: 
    // public DLList stuff goes here

};

为什么这是个好主意?封装。如果外面没有人DLList应该知道它的Node存在。他们当然不应该被允许得到他们的手。一些白痴可以delete在没有正确删除它的情况下进行操作。他们可能会不小心弄坏它。不要给他们机会。给他们迭代器并给他们数据。永远不要给他们一个Node.


推荐阅读