我知道我们不能定义将不完整类型作为参数的函数,因此预计以下代码无法编译并出现error C2027: use of undefined type '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) 中对这种情况进行了特殊处理
The type of a parameter or the return type for a function definition shall not be an incomplete class type (possibly cv-qualified) unless the function definition is nested within the member-specification for that class (including definitions in nested classes defined within the class).
这个规则可以被看作是另一个类似规则的“卫星” - 那个说类类型总是从类成员函数的主体,默认参数和构造函数初始化器中看到的整体(并且作为完整类型)列出。参见 9.2/2 (C++03)
A class is considered a completely-defined object type (3.9) (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments and constructor ctor-initializers (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.
请注意,在关闭 }
之前的所有其他上下文中,该类被认为是不完整的
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`
{}
};
关于c++ - 不完整类型 : class usage before definition vs. 前向声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17585191/