什么时候向前声明还不够?

时间:2019-05-23 13:08:45

标签: c++ class overloading definition incomplete-type

#include问题

class widget { };

class fubar : public widget { // 1

    void value_parameter(widget); // 2    
    void ref_parameter(widget &); // 3
    void ptr_parameter(widget *); // 4

    virtual void value_parameter(widget); // 5
    virtual void ref_parameter(widget &); // 6
    virtual void ptr_parameter(widget *); // 7

    widget value_return(); // 8
    widget & ref_return(); // 9
    widget * ptr_return(); // 10

    widget instance_value_member; // 11
    widget & instance_ref_member; // 12
    widget * instance_ptr_member; // 13

    static widget static_value_member; // 14
    static widget & static_ref_member; // 15
    static widget * static_ptr_member; // 16
};

其中哪些行需要包含? (#include "widget.hpp"

3 个答案:

答案 0 :(得分:5)

Widget的完整定义是必需的:

  • #1class fubar : public widget),我们需要基类定义。
  • #11widget instance_value_member;),我们需要成员定义。

转发声明足以满足其他要求。

答案 1 :(得分:3)

没有。

class widget { };定义了完整类型

如果您编写class widget;,即转发类声明,那将是另一回事。然后,由于继承的原因,您需要一个完整类型,因此这些函数将不再需要#include

答案 2 :(得分:1)

我认为您的意思是前瞻性声明

.addEventListener

代替定义

clicker.addEventListener("click", function executeOnEvent (event) {
  console.log("it works");
  console.log(event);
});

在这种情况下,类声明的第一行标题

class widget;

需要窗口小部件的完整类型定义。否则,类fubar的大小将是未知的。

除此行外,所有其他声明不需要小部件的竞争类型定义

class widget { };

请考虑到静态数据成员可能是不完整的类型,因为它们是类定义中的声明(使用说明符constexpr声明时除外)。例如这行

class fubar : public widget { // 1

不需要完整的小部件类型定义。

此外,您可能无法通过以下方式重载成员函数

widget instance_value_member; // 11

这将重载具有相同名称和参数列表的虚拟和非虚拟函数。