为什么嵌套类的成员函数不需要完整的类型?

时间:2018-04-02 04:27:54

标签: c++ forward-declaration

示例:

 class A
{
  class B
  {
    A c;//error!A is an incomplete type
    void test() { A b;/*OK,but why?*/ }
  };
};

代码片段对我来说似乎很奇怪,A这两种用法的区别是什么?

2 个答案:

答案 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 Aforward-declaration,其中:

  

声明一个类类型,稍后将在此范围内定义。在定义出现之前,此类名称的类型不完整。这允许相互引用的类:

class A之前class B尚未“完全”定义。

因此,class A是前向声明和不完整类型。

然而,

void test() { A b;/*OK,but why?*/ }
  

如果forward声明出现在本地作用域中,它会隐藏先前声明的类,变量,函数以及可能出现在封闭作用域中的所有其他同名声明:

因此,可以在本地范围内声明A