关于C++具有自我参考的类

About C++ classes with self reference

本文关键字:参考 自我 C++ 关于      更新时间:2023-10-16

我有点困惑...

为什么在C++允许这样做:

static int t = 0;
class A
{
    public:
        A() : m(t++)
        {
            cout << "C:" << m << endl; 
            if(t >= 5)
            {
                A a;                      // <<<< ----- THIS line
                throw( a);
            }
        }            
        int m;
};

但这不是:

static int t = 0;
class A
{
    public:
        A() : m(t++)
        {
            cout << "C:" << m << endl; 
        }
        A a;                            // <<<< ----- THIS line
        int m;
};

第二个没有按预期编译(是的,我知道为什么它没有编译:在代码的这一点上,A仍然不完整(......

但。。。第一个编译得很好(并做了它应该做的事情,即:在语句上使应用程序崩溃:A a[10]; (。构造函数中的A是完整类型吗?还可以为我指出一些针对这种情况C++标准条目吗?

当你声明任何变量时,编译器应该知道它的大小。 在第二个示例中,您将在A内部创建一个A对象,因此编译器将无法计算A的大小来分配内存。

还可以为我指出一些C++这种情况的标准条目吗?

是的,C++标准草案说,直到结束}才完全定义类,这是在第9.2类成员2段中:

在类说明符的结尾 } 处被视为完全定义的对象类型 (3.9((或完整类型(。[...]

并且类的所有非静态数据成员必须是完整的,来自第 9 段:

非静态 (9.4( 数据成员不得具有不完整的类型。特别是,类 C 不应包含类 C 的非静态成员,但它可以包含指向类 C 对象的指针或引用。

但它在构造函数中也被认为是完整的,在第 2 段中也是如此:

[...]在类成员规范中,类在函数体、默认参数、[...]

尽管静态成员可能不完整,但第 9.4.2 节静态数据成员2 段:

静态数据成员在其类定义中的声明不是定义,并且可能属于 cv 限定的 void 以外的不完整类型。[...]

不允许类包含自身也是有意义的,因为这需要无限的空间,因为自引用永远不会结束,A包含包含AA......