为什么嵌套类的成员函数不需要完整类型?
Why doesn't the member func of nested class need a complete type?
示例:
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
是可以的。
相关文章:
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 为什么转换函数声明不需要至少一个定义类型说明符
- 为什么不需要在 C++20 中的依赖类型之前指定"typename"?
- 为什么在以下情况下不需要为依赖类型使用typename
- 为什么 pair 在初始化中不需要类型
- 为什么在VS2015中模板相关的嵌套类型名称中不需要typename关键字?
- 为什么嵌套类型的基类不需要"typename"?
- 为什么一元运算符和不需要完整类型?
- 为什么嵌套类的成员函数不需要完整类型?
- 为什么 c++ lambda 捕获不需要类型声明?
- 不需要增量锁的 C++ 计数器类型
- 如果 std::shared_ptr 是从非 null 构造的,为什么它不需要知道完整的类型?
- 检测类型何时不需要调用其析构函数
- 模板类和处理不需要的类型声明的良好实践
- 哪里需要完整的类型(不需要)
- 使用函子的返回类型来声明模板方法的返回类型,不需要decltype
- c++调用约定是否受标准约束,因为在声明fn时不需要定义函数的返回类型
- 退货类型中不需要模板参数
- c++:包含对象的确切类型,不需要强制类型转换
- 在c++中,如何解析文本文件后面不需要的文本中的任何数据类型