在源文件中包含类而不是标题
Posted
技术标签:
【中文标题】在源文件中包含类而不是标题【英文标题】:Include Class in Source File Rather Than Header 【发布时间】:2013-01-17 21:15:40 【问题描述】:我有 3 个课程:
ClassA.h
ClassA
public:
ClassA();
;
ClassB.h
#include "ClassA.h"
classB
public:
ClassB();
private:
ClassA m_classA;
;
ClassC.h
#include "ClassB.h"
ClassC
public:
ClassC();
private:
ClassB m_classB;
;
ClassC 需要 ClassB,ClassB 需要 ClassA。 ClassC 不需要 ClassA,所以我应该将 ClassB 标头中的 #include "ClassA.h" 放在源文件中并创建一个全局对象还是有更好的方法?
ClassB.cpp
#include "ClassB.h"
#include "ClassA.h"
ClassA g_classA;
【问题讨论】:
@Rapptz 前向声明没有声明完整的类型,他没有使用指针。 @Nick 我似乎误读了这个问题。 【参考方案1】:ClassB
有一个ClassA
对象,所以它的类声明需要ClassA
的完整声明。因此,无论ClassC
发生什么,您都需要在ClassB.h
* 中包含ClassA.h
标头。
如果您想避免包含标头,您可以做的是存储一个(智能)指向classA
的指针并转发声明它。那么您只需要在classB.cpp
中包含classA.h
。这是一个简单的例子:
在A.h
class A ;
在B.h
#include <unique_ptr>
class A; // forward declaration of A
class B
public:
B();
private:
std::unique_ptr<A> a_; // C++11 smart pointer expressing unique ownership
;
在B.cpp
#include "B.h"
#include "A.h" // we need the full declaration here.
B::B() : a_(new A())
* 严格来说,ClassA.h
可以包含在其他文件中,只要它间接包含在 ClassB.h
中即可。但最好在需要的地方包含您需要的内容,而不是依赖于间接包含。
【讨论】:
对于编写的代码绝对正确,但是...您可以使用 pimpl 来打破依赖关系。 包含ClassA.h
之前 ClassB.h
与包含它inside ClassB.h
一样有效。这可能是个好建议,但不是唯一的方法。
@MarkRansom 是的,我为此添加了一个脚注。
如果您正在处理一个大型项目并且 ClassB 开始变得更大并且包含多个类,您是否仍将所有这些标题包含在 ClassB 的标题中并在那里创建对象。还是在 ClassB 的源文件中包含头文件并创建全局类对象并跳过头文件声明?
@JamesMoore “全局类对象”是一个正交概念。对于某种类型的数据成员,就像您拥有的那样,包含类的每个实例都有自己的包含类型的实例。如果你想最小化编译时依赖,你可以做的是让你的类持有(智能)指向其他类型的指针,并在头文件中转发声明这些类型而不是包含它们的头文件。然后在源文件中包含头文件。我将添加一个小例子。以上是关于在源文件中包含类而不是标题的主要内容,如果未能解决你的问题,请参考以下文章