我知道已经提出了类似的问题,并且有些答案描述了在下面描述的情况中,前向声明是不够的。但是,这些答案并没有说明为什么它还不够。因此,我不认为这是一个重复的问题。
我有一些困难要理解为什么编译器必须在以下情况下看到数据类型的定义(前言声明是不够的):
我们假设我们有一个简单的“main.cpp”,如下所示 绝对没有,除了包括头文件“MyClass.hpp”
#include <MyClass.hpp>
int main(int argc, char **argv)
{
return 0;
}
现在,让我们考虑一下“MyClass.hpp”的内容如下:
#include <vector>
class Data1;
class MyClass
{
public:
MyClass(); // default constructor
MyClass(MyClass const & p_other); // copy constructor
MyClass(MyClass && p_other); // move constructor
~MyClass(); // destructor
MyClass & operator=(MyClass const & p_rhs); // copy assignment
MyClass & operator=(MyClass && p_rhs); // move assignment
private:
Data1 * m_a; // forward decl. always OK
Data1 m_b; // forward decl. always not OK
std::vector<Data1> m_c; // forward decl. OK if MyClass is not instantiated
};
MyClass包含几个成员变量:
“Data1”的定义既不包含在“MyClass.hpp”中也不包含在“main.cpp”中。它只是向前宣布。
编译器永远不会遇到成员变量“m_a”的问题,它不需要编译“main.cpp”的定义 - 即使我们要将“MyClass”实例化。
因为我们没有实例化“MyClass”,所以编译器也没有成员变量“m_c”的问题。在这种情况下,它也不需要定义“Data1”。
但是,编译器的成员变量“m_b”存在问题:
Impl1.hpp:16:24:错误:字段'm_b'的类型'Data1'不完整
我的简单问题是:为什么?
请考虑我们有用户定义的默认构造函数,复制构造函数, 移动构造函数,用户定义的析构函数和用户定义的复制分配 运算符和移动赋值运算符,即编译器不必 为任何这些构造函数/方法生成代码。所以为了什么目的 编译器只需编译“main.cpp”时需要查看“Data1”的定义吗?
有人知道答案吗?
答案 0 :(得分:0)
MyClass
的大小取决于Data1
的大小,Data1
的大小只能从<div class="div-class"></div>
的定义中获知。这就是为什么你不能将不完整的类型作为你的类型中的字段。