[英]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)中对这种情况给予特殊处理
函数定义的参数类型或返回类型不应是不完整的类类型(可能是cv限定的),除非函数定义嵌套在该类的成员规范中(包括在类中定义的嵌套类中的定义) )。
此规则可以被视为另一个类似规则的“卫星” - 表示类类型总是从类成员函数,默认参数和构造函数初始化列表的主体中完整地看到(并且作为完整类型)。 见9.2 / 2(C ++ 03)
在类说明符的结束时,类被认为是完全定义的对象类型(3.9)(或完整类型)。 在类成员规范中,该类在函数体,默认参数和构造函数ctor-initializers(包括嵌套类中的这类事物)中被视为完整。 否则,它在其自己的类成员规范中被视为不完整。
请注意,在其他情况下结束前}
类被认为是不完整
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`
{}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.