我有一个Stack类,使用模板,它的方法之一是“push”,写在下面:
template <class T>
void Stack<T>::push(T _data){
Node<T>* temp = new Node<T>;
temp->data = _data;
temp->next = head;
head = temp;
}
堆栈适用于int
、double
、string
、char
....
但是它说
prog.cpp:32: note: synthesized method ‘Node<Tree>::Node()’ first required here
当我使用类“Tree”作为数据类型时。 我不明白,为什么它适用于“string”而不适用于“Tree”,它们都是类,而不是原始类型。
http://ideone.com/NMxeF (忽略另一个错误,我的IDE只在第32行给出一个错误和一些警告)
帮助!
最佳答案
阅读实际代码后进行编辑(上面显示的“注释”对真正的问题有相当大的误导性)。
查看代码,您尝试在其中使用 new Node<T>;
,这需要 T 的默认构造函数(在本例中为 Tree
),因为您的 Node 模板包含 T 的实例:
struct Node {
T data; // <--- instance of T, not being initialized in your code.
Node *next;
};
Tree
没有默认构造函数,因此失败(注释向您展示了需要默认构造函数的位置)。
关于如何解决这个问题,您有几种选择。最明显的是 Node
保存指针或对 T
的引用而不是包含 T 的实际实例。
另一个是 Node
的构造函数引用一个(可能是常量的)T,并将该 T 复制到节点中:
class Node {
T data;
Node *next;
public:
Node(T const &dat) : data(dat), next(0) {}
};
这两种方法之间的选择是相当基本的。如果您让 Node 存储指向 T 的指针/引用,那么调用代码将负责确保只要 Node 存在,传递的对象就保持有效。节点和调用代码将共享对 T 的单个实例的访问。
相比之下,如果你将传递的对象复制到节点中,那么这个拷贝将在Node
时被销毁。被摧毁。您传递给节点的原始 T(树,在您的情况下)将保留调用代码的责任,Node
将对其拷贝负责。
在通常情况下,您倾向于选择后者——它提供更清晰的语义,并保持数据所有权清晰。但是,在树的情况下,如果可以避免的话,您可能不想将整个树复制到节点中。一种折衷的做法是使用类似 Node<shared_ptr<Tree> >
的东西。反而。 shared_ptr 可以保持快速和廉价的复制,同时避免编写仅适用于几种对象和情况的节点。这也非常明确地表明您仅存储一个指针,该指针提供对原始对象的共享访问。
关于c++ - 不能将一个类用作另一个类中的模板类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10150410/