在C ++中,类是否可以包含指向在构造函数中初始化的同一个类的指针?

时间:2018-03-02 01:27:19

标签: c++ pointers

我知道一个班级不能拥有同一班级的成员,例如

class Sample {
    int a = 0;
    Sample s; // error, object would need infinite size
};

但是如何拥有一个指针是好的?

class Sample {
    // this compiles, but isn't it essentially the same
    // as above? 
    Sample() { s = new Sample(); } 
    int a = 0;
    Sample *s; 
};

3 个答案:

答案 0 :(得分:1)

允许指针作为成员,因为指针具有固定大小(32位应用程序中为4个字节,64位应用程序中为8个字节),因此编译器可以在编译时知道Sample的完整大小,它不依赖于指针在运行时指向的内容。

Sample构造函数中创建Sample的实例不是语法错误,因此编译器允许它,但它会在运行时导致无限递归循环。所以不要这样做。

答案 1 :(得分:1)

一般来说,编译器擅长检测类型的问题,而不善于检测的问题。

在后一种情况下,有时那是因为它不能(它怎么能知道十年后发生的事情?),有时它是因为它不能真正被打扰(读:标准不需要它做数学上困难的事情,因为那将是一种意思)。

在第一个示例中,递归定义是类型显示的问题。编译器总是知道你已经完成了它。事实上,它没有办法创建一个与源代码匹配的程序:没有这样的东西可以在数学上存在 - 它会永远存在。

但运行时间接开辟了新的机会!指针不 指向任何东西。您可以将s保持未初始化状态,或将其初始化为nullptr,这样就可以了。您可以通过if电话将选项保留为rand()。编译器可以做的最好的事情是分析构造函数体,看看你是否递归实例化Sample。但最终,这比编译器或标准更愿意放入 1 ,所以它就成了你的问题。

简而言之:就是它的方式

1。如果你的构造函数体在另一个翻译单元中怎么办?这次不是,但C ++喜欢一般规则......

答案 2 :(得分:0)

class Sample {
    int a = 0;
    Sample s; // error, object would need infinite size
};

Sample的定义在你声明Sample s;的地方未完成,因此编译器不知道应该分配多少大小......它不知道是什么sizeof(Sample)

指向自身的指针,即Sample *s;,是标准大小,具体取决于您编译代码的目标平台。