代码之家  ›  专栏  ›  技术社区  ›  choxsword

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

  •  10
  • choxsword  · 技术社区  · 6 年前

    示例:

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

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

    2 回复  |  直到 6 年前
        1
  •  14
  •   Brian Bi    6 年前

    [class.mem]/6规定:

    在结束时,类被视为完全定义的对象类型(6.9)(或完全类型) } 类说明符 。在班级内 构件规范 ,则该类被视为函数内的完整类 主体、默认参数、, 无异常说明符 ,和默认成员初始值设定项(包括 嵌套类)。否则,它在其自身类别中被视为不完整 构件规范

    对象的定义(如 A b; A c; )要求对象具有完整的类型。正如上面一段所述,类类型在其自身定义中是不完整的,但在某些地方除外:即在成员函数体内部和其他一些地方。

    此规则允许在内联定义的成员函数内编写非平凡代码,同时也禁止类(直接或间接)包含自身。

        2
  •  1
  •   Joseph D.    6 年前

    如编译错误所示:

    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

    因此 A类 是转发声明和不完整类型。

    然而,对于

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

    如果转发声明出现在局部作用域中,它将隐藏以前声明的类、变量、函数以及可能出现在封闭作用域中的所有其他同名声明:

    因此,拥有 A 在本地范围中声明。