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

Why doesn't the member func of nested class need a complete type?

本文关键字:类型 不需要 函数 嵌套 成员 为什么      更新时间:2023-10-16

示例:

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

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

[class.mem]/6 指定:

}类说明符。在类成员规范中,类被视为函数内的完整 正文、默认参数、noexcept-specifier和默认成员初始值设定项(包括此类内容 嵌套类)。否则,它在其自己的类成员规范中被视为不完整。

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

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

如编译错误所示:

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是一份前瞻性声明,其中:

声明稍后将在此作用域中定义的类类型。在出现定义之前,此类名的类型不完整。这允许相互引用的类:

因为class A直到class B才被"完全"定义。

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

但是,对于

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

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

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