类型不完整:定义前的类用法与前向声明
Incomplete type: class usage before definition vs. forward declaration
我知道我们不能定义以不完整类型为参数的函数,所以下面的代码编译失败,错误C2027:使用未定义的类型"Derived"
class Derived;
class Base{
public:
void test(Derived d){ cout<<"test"<<endl; }
};
class Derived : public Base{
int j;
};
按照同样的逻辑,当test()获取一个Base对象时,我预计编译会失败,在那之前,该对象的类型是不完整的。然而,它并没有,下面的代码编译了精细的
class Derived;
class Base{
public:
void test(Base b){ cout<<"test"<<endl; }
};
class Derived : public Base{
int j;
};
在定义类时,我们所拥有的不完整类类型与正向声明所公开的不完整类型之间有区别吗?
逻辑不一样。不同之处在于,在第二个示例中,函数Base::test()
使用自己类Base
的对象(而不是完全外来的类Derived
)。
该语言在8.3.5/6(C++03)中对这种情况进行了特殊处理
参数的类型或函数定义的返回类型除非函数定义嵌套在的成员规范中该类(包括在类)。
这个规则可以被视为另一个类似规则的"卫星",即从类成员函数、默认参数和构造函数初始值设定项列表的主体中,类类型总是被视为完整的(和完整的类型)。见9.2/2(C++03)
类在的结束}处被视为完全定义的对象类型(3.9)(或完全类型)类说明符。在类成员规范中,该类被视为函数内的完整类主体、默认参数和构造函数-构造函数初始值设定项(包括嵌套类中的这些东西)。否则它在自己的类成员规范中被认为是不完整的。
注意,在关闭}
之前的所有其他上下文中,类被认为是不完整的
struct S {
S foo(S s) // <- OK, due to 8.3.5/6
{ return s; }
void bar(int a = sizeof(S)) // <- OK, due to 9.2/2
{ S s; } // <- OK, due to 9.2/2
int (*baz())[sizeof(S)] // <- ERROR: incomplete type in `sizeof`
{ return NULL; }
void qux(int a[sizeof(S)]) // <- ERROR: incomplete type in `sizeof`
{}
};
相关文章:
- .cpp和.h文件中的模板专用化声明
- 未在作用域中声明unordered_map
- C++避免重复声明的语法是什么
- 如何确保C++函数在定义之前声明(如override关键字)
- 错误:未在此范围内声明'reverse'
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 为什么在定义函数之前先声明它
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- #ifdef和未声明的标识符
- 没有显式声明的int[]中的foreach
- 在基于范围的for循环中使用结构化绑定声明
- 在将变量声明为引用时,堆在释放后使用
- C++:无法访问声明的受保护成员
- 在 VC++ 中访问一个文件中声明的变量.(外部关键字用法)
- c++使用Boost库示例中的声明关键字用法
- 类型不完整:定义前的类用法与前向声明
- c++结构声明和保存IP +连接的用法
- 在函数内部声明函数的用法
- 头文件和多类用法(EDIT:正向声明)
- 在类中声明2d数组及其后面的用法