类型不完整:定义前的类用法与前向声明 [英] Incomplete type: class usage before definition vs. forward declaration

查看:223
本文介绍了类型不完整:定义前的类用法与前向声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我们无法定义以不完整类型为参数的函数,因此可以预期以下代码因错误 C2027而无法编译:使用未定义类型'衍生'

I know we can not define functions taking incomplete type as parameter, so it is expected the below code fails to compile with 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对象时,编译会失败,而该对象直到那时仍是不完全类型的.但是,事实并非如此,下面的代码可以很好地编译

By the same logic, I would expect compilation to fail when test() takes an object of Base, which is of incomplete-type till that point. However, it does not, and the following code compiles fine

class Derived;
class Base{
public:
    void test(Base b){ cout<<"test"<<endl; }
};
class Derived : public Base{
    int j;
};

在定义类时,我们所拥有的不完整类类型与前向声明所暴露的不完整类型之间是否有区别?

Is there a difference between the incomplete class type we have while a class is being defined and the incomplete-type exposed by a forward declaration?

推荐答案

逻辑不一样.区别在于第二个示例函数Base::test()使用其自己的类Base的对象(与完全外来的类Derived相对).

The logic is not the same. The difference is that in your second example function Base::test() uses objects of its own class Base (as opposed to a completely foreign class Derived).

在8.3.5/6(C ++ 03)中,语言对该情况进行了特殊处理

The language gives a special treatment to this situation in 8.3.5/6 (C++03)

参数的类型或函数定义的返回类型 不得为不完整的类类型(可能具有cv限定),除非 函数定义嵌套在的成员规范内 该类(包括 类).

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)

This rule can be seen as a "satellite" for another similar rule - the one that says that the class type is always seen in its entirety (and as complete type) from bodies of class member functions, default arguments and constructor initializer lists. See 9.2/2 (C++03)

在类的结尾处,类被视为完全定义的对象类型(3.9)(或完整类型). 类说明符.在类成员规范内,该类在功能内被视为完整 正文,默认参数和构造函数ctor初始化程序(包括嵌套类中的此类内容).否则 在其自身的类成员规范中,它被认为是不完整的.

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.

请注意,在所有其他上下文中,在结束}之前,该类均被视为不完整

Note that in all other contexts before the closing } the class is considered to be incomplete

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`
    {}
};

这篇关于类型不完整:定义前的类用法与前向声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆