我有点困惑......
为什么在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 ++标准条目吗?
答案 0 :(得分:5)
当您声明任何变量时,编译器应该知道它的大小。如果您的第二个示例是在A
内创建A
的对象,那么编译器将无法计算A
的大小来分配内存。
答案 1 :(得分:3)
还可以为我指出一些C ++标准条目吗?
是的,draft C++ standard表示在结束}
之前尚未完全定义某个类,这部分位于9.2
类成员段 2 :
在classspecifier的close}处,类被视为完全定义的对象类型(3.9)(或完整类型)。 [...]
并且类的所有非静态数据成员必须完整,从段落 9 :
非静态(9.4)数据成员不得有不完整的类型。特别是,类C不应包含类C的非静态成员,但它可以包含指向C类对象的指针或引用。
但在构造函数中也认为它在 2 :
段落内完成[...]在类成员规范中,该类在函数体中被认为是完整的,默认参数,[...]
虽然静态成员可能不完整,但部分9.4.2
静态数据成员段 2 :
静态数据成员在其类定义中的声明不是定义,除了cv-qualified void之外可能是不完整的类型。[...]
不允许类包含自身也是有意义的,因为这需要无限空间,因为自引用永远不会结束,A
包含A
,其中包含A
...