This question already has answers here:
When can I use a forward declaration?
(13个回答)
3年前关闭。
我知道已经问过类似的问题,并且有答案说明在下面描述的情况下,向前声明还不够。但是,这些答案并不能说明原因。因此,我认为这不是重复的问题。
在以下情况下,我很难理解为什么编译器必须查看数据类型的定义(向前声明是不够的):
让我们考虑一下我们有一个简单的“main.cpp”,如下所示
除了包含头文件“MyClass.hpp”,绝对没有其他内容
现在,让我们考虑“MyClass.hpp”的内容如下:
MyClass包含几个成员变量:
“m_a”是指向“Data1”的指针 “m_b”是“Data1”, 的实例“m_c”是一个元素类型为“Data1”的 vector 。
“Data1”的定义既不包含在“MyClass.hpp”中,也不包含在“main.cpp”中。它只是向前声明。
编译器永远不会对成员变量“m_a”产生问题,即使我们要实例化“MyClass”,它也不需要定义其来编译“main.cpp”。
因为我们没有实例化“MyClass”,所以编译器的成员变量“m_c”也没有问题。在这种情况下,它也不需要定义“Data1”。
但是,编译器存在成员变量“m_b”的问题:
我的简单问题是:为什么?
请考虑我们拥有用户定义的默认构造函数,复制构造函数,
移动构造函数,用户定义的析构函数和用户定义的副本分配
运算符和移动赋值运算符,即编译器不必
为这些构造函数/方法中的任何一个生成代码。那是为了什么目的
编译器仅编译“main.cpp”时需要查看“Data1”的定义吗?
有人知道答案吗?
(13个回答)
3年前关闭。
我知道已经问过类似的问题,并且有答案说明在下面描述的情况下,向前声明还不够。但是,这些答案并不能说明原因。因此,我认为这不是重复的问题。
在以下情况下,我很难理解为什么编译器必须查看数据类型的定义(向前声明是不够的):
让我们考虑一下我们有一个简单的“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”产生问题,即使我们要实例化“MyClass”,它也不需要定义其来编译“main.cpp”。
因为我们没有实例化“MyClass”,所以编译器的成员变量“m_c”也没有问题。在这种情况下,它也不需要定义“Data1”。
但是,编译器存在成员变量“m_b”的问题:
我的简单问题是:为什么?
请考虑我们拥有用户定义的默认构造函数,复制构造函数,
移动构造函数,用户定义的析构函数和用户定义的副本分配
运算符和移动赋值运算符,即编译器不必
为这些构造函数/方法中的任何一个生成代码。那是为了什么目的
编译器仅编译“main.cpp”时需要查看“Data1”的定义吗?
有人知道答案吗?
最佳答案
MyClass
的大小取决于Data1
的大小,只能从Data1
的定义知道。这就是为什么您不能在类型中使用不完整的类型作为字段。