示例:
class A
{
class B
{
A c;//error!A is an incomplete type
void test() { A b;/*OK,but why?*/ }
};
};
代码片段对我来说似乎很奇怪,A
这两种用法的区别是什么?
答案 0 :(得分:14)
[class.mem] / 6指定:
在结束
}
处,类被视为完全定义的对象类型(6.9)(或完整类型) 类说明符。在类 member-specification 中,该类在函数内被视为完整 body,默认参数, noexcept-specifiers 和默认成员初始值设定项(包括 嵌套类)。否则,它在其自己的类 member-specification 中被视为不完整。
对象的定义(如A b;
或A c;
)要求对象具有完整类型。正如上面的段落所述,类型在其自己的定义中是不完整的,除了在某些地方:即内部成员函数体和其他一些地方。
这条规则可以在内联定义的成员函数中编写非平凡的代码,同时也禁止类包含它自己(直接或间接)。
答案 1 :(得分:1)
如编译错误中所示:
prog.cpp:8:7: error: field ‘c’ has incomplete type ‘A’
A c;//error!A is an incomplete type
^
prog.cpp:4:8: note: forward declaration of ‘class A’
class A
^
Class A
是forward-declaration,其中:
声明一个类类型,稍后将在此范围内定义。在定义出现之前,此类名称的类型不完整。这允许相互引用的类:
class A
之前class B
尚未“完全”定义。
因此,class A
是前向声明和不完整类型。
然而,
void test() { A b;/*OK,but why?*/ }
如果forward声明出现在本地作用域中,它会隐藏先前声明的类,变量,函数以及可能出现在封闭作用域中的所有其他同名声明:
因此,可以在本地范围内声明A
。