底部的代码生成以下编译时错误。如果我使用std::vector<Node>
或std::array<unique_ptr<Node>, 3>
,错误就会消失。有人可以解释这是关于什么的吗?
main.cpp中包含的文件:1:0:/usr/include/c++/4.9/array:In 'struct std :: array'的实例化:main.cpp:9:23:
的前向声明
从这里需要/usr/include/c++/4.9/array:97:56:错误: 'std :: array&lt; _Tp,_Nm&gt; :: _ M_elems'的类型不完整 typename _AT_Type :: _输入_M_elems; ^ main.cpp:3:7:错误:'类Node'类节点
#include <array>
class Node
{
public:
Node(Node* parent, int x) : parent_(parent), x_(x) {}
Node* parent_;
int x_;
std::array<Node, 3> children_; // ERROR
};
答案 0 :(得分:4)
正如其他答案所述,这里的根本问题是你在该类型的定义中使用了一个类型。
原因这是一个问题,因为编译器必须知道类型的大小才能使它成为数据成员。因为您尚未完成声明Node
类型,所以编译器不知道它应该为Node
类型的数据成员使用多少空间。
指针 工作的原因是因为所有指针在内存中的大小都相同,所以指向的大小会有所不同,这只是你需要的知道何时取消引用指针。
因此,在std::array<Node, 3>
定义中使用Node
不起作用,因为std::array
将其内存放在声明的位置(在函数中,这是堆栈,在一个对象中,它位于对象本身中)。要弄清楚需要多少内存,需要知道Node
的大小,并且存在问题。
使用std::unique_ptr<Node>
是正常的,原因与普通指针相同:指针的大小始终相同。
使用std::vector<Node>
很好(原则上,但不一定在实践中)出于同样的原因,但可能不那么明显:你可以认为vector
有2个数据成员,a指向Node
s数组和大小的指针。关键部分是指针。因为只有vector
的“句柄”存在于Node
的内存中,并且数据被分配到其他地方,所以这是一种非常好的存储方式。
鉴于语言的限制,表达意图的最好方法可能是:
std::array<std::unique_ptr<Node>, 3>
您仍然拥有固定数量的子级,自动内存管理,并且不再遇到不知道该数据成员的存储空间有多大的问题。
对于它的价值,同样的推理是启用pimpl习语的原因。
答案 1 :(得分:3)
Node
显然不能包含三个Nodes
这将是一种递归关系,只能在以下两个条件之一结束:
您的选择。 IMO既不是最佳的。
答案 2 :(得分:1)
您正在尝试声明该节点包含一个包含3个节点的成员。这根本不可能,因为它是无限递归。
的std ::矢量&lt;节点&gt;因为矢量最初为空并且动态添加,所以可以正常工作。
的std ::阵列&LT;的std ::的unique_ptr&LT;节点&gt;,3&gt;可行,因为这种类型的数组只包含指向Node对象的指针,而不包含对象本身。
答案 3 :(得分:0)
就我而言,在数组声明中使用类类型之前,我只有类类型的声明。 C ++期待定义。