我的代码有 2 个相关类:Class1
有指向Class2
实例的指针字段;Class2
有指向Class1
实例的指针字段:
类1.hpp
#ifndef __CLASS_1_HPP
#define __CLASS_1_HPP
#include "all.hpp"
class Class1
{
public:
Class1();
private:
Class2 *c2;
};
Class1::Class1()
{
c2 = new Class2();
}
#endif // __CLASS_1_HPP
类2.hpp
#ifndef __CLASS_2_HPP
#define __CLASS_2_HPP
#include "all.hpp"
class Class2
{
public:
Class2();
private:
Class1 *c1;
};
Class2::Class2()
{
c1 = new Class1();
}
#endif // __CLASS_2_HPP
全部.hpp
#ifndef __ALL_HPP
#define __ALL_HPP
class Class1;
class Class2;
#include "class1.hpp"
#include "class2.hpp"
#endif // __ALL_HPP
主.cpp
#include "all.hpp"
int main() {}
当我尝试编译它时,我得到无效使用不完整的类型 Class2在线c2 = new Class2();
.在 .hpp 和 .cpp 上划分 .hpp 文件无济于事!
让我们通过编译器的眼镜看到所有这些。在预处理器完成它工作之后,你最终会得到一个所谓的翻译单元,如下所示:
主.cpp:
class Class1;
class Class2;
class Class1
{
public:
Class1();
private:
Class2 *c2;
};
Class1::Class1()
{
c2 = new Class2(); // error: invalid use of incomplete type 'class Class2'
/// So all what the compiler knows at this point
/// about Class2 is that's a class, but not how to create it.
/// It was just declared but not defined yet.
}
class Class2
{
public:
Class2();
private:
Class1 *c1;
};
Class2::Class2()
{
c1 = new Class1();
}
int main() {}
在c2 = new Class2();
行,编译器对 Class2 的所有了解都是一个类,但不知道如何创建它。它刚刚宣布但尚未定义。
因此,通常通过将类成员函数定义放在单独的源(例如.cpp)文件中来解决此问题,这些文件包含具有两个类定义的头文件。
1.cpp类:
#include "class1.hpp"
#include "class2.hpp"
Class1::Class1()
{
c2 = new Class2();
}
类2.cpp:
#include "class2.hpp"
#include "class1.hpp"
Class2::Class2()
{
c1 = new Class1();
}
并且只在头文件中保留类定义:
#ifndef __CLASS_1_HPP
#define __CLASS_1_HPP
class Class2;
class Class1
{
public:
Class1();
private:
Class2 *c2;
};
#endif // __CLASS_1_HPP
包括all.hpp
。因此,Class1
和Class2
被转发,直到完整的定义。
然后包括class1.hpp
。Class1
的构造函数既是声明的,也是定义的。
这个 ctor 的定义调用new Class2()
,但此时Class2
的构造函数还没有定义。编译器只知道 Class1 存储指向 Class2 类型的对象的指针,而不知道如何生成该对象。
也许您想将声明(在标头中)与定义(在.cpp代码中)分开
我猜你是局促:
class Class1
{
public:
Class1();
private:
Class2 * c2;
};
Class1::Class1()
{
c2 = new Class2();
}
进入1.hpp 您需要做的是:
类1.hpp
#include all.hpp
class Class1
{
public:
Class1();
private:
Class2 * c2;
};
和
类1.cpp
#include "Class1.hpp"
Class1::Class1()
{
c2 = new Class2();
}
与 Class2.cpp/Class2.hpp 相同 在您的代码中,您没有调用 c1 和 c2 (Class1::Class1()
) 的构造函数,因为您没有在那里创建对象,而是在不起作用的 hpp 中创建对象。如果要在标头中创建对象,可以尝试初始值设定项。