我有一个 B 类,我想调用 A 类的成员。所以:
1.
//A.h
class B;
class A
{
private:
B* m_p;
};
//a.cpp
#include "B.h"
2.
// A.h
#include "B.h"
class A
{
private:
B * impl_;
};
当一个没有太多依赖的小项目涉及时,哪种方式更好,这两者是否相似?
我有一个 B 类,我想调用 A 类的成员。所以:
1.
//A.h
class B;
class A
{
private:
B* m_p;
};
//a.cpp
#include "B.h"
2.
// A.h
#include "B.h"
class A
{
private:
B * impl_;
};
当一个没有太多依赖的小项目涉及时,哪种方式更好,这两者是否相似?
你这样做的第一种方式意味着在 中a.h
,存在是class B
已知的,但不是它的定义。这限制了您可以对B
inside执行的操作a.h
。例如,你可以有 type 的变量B *
,但不能有 typeB
的变量(因为对于 type 变量的声明,B
编译器必须能够看到 的完整定义B
)。此外,如果您有 type 的变量,B *
则不能取消引用指针(因为也B
必须知道 的定义)。
因此,您的第二选择——没有这些问题——是首选,这是大多数人大部分时间使用的。
只有在第一种方法可能有用的特殊情况下。例如:
.h
文件相互包含(但是您可能会遇到一些进一步的问题,也涉及包含保护;这通常很困难并且应该避免);b.h
非常大且复杂,因此您希望尽可能避免包含它,因为它会减慢编译过程。您的第一种方法是前向声明。您的第二个实际上包括 B 类。
什么时候使用一个而不是另一个?
答:1。
看看http://www.umich.edu/~eecs381/handouts/handouts.html
C 头文件指南
C++ 头文件指南(由密歇根大学 EECS 系的 David Kieras 撰写)说:
准则 #10。如果类型 X 的声明不完整,请使用它而不是 #include 其标头 Xh。如果另一个结构或类类型 X 仅作为指针或引用类型出现在头文件的内容中,那么您不应该#include Xh,而只需将不完整的 X 声明(也称为“前向”声明)放在头文件的开头,如:
class X;
请参阅讲义 不完整的声明以获取有关此强大且有价值的技术的更多讨论。请注意,标准库包含一个不完整声明的标头,该标头通常足以满足该<iostream>
库的需要,名为<iosfwd>
. #include<iosfwd>
尽可能,因为<iostream>
头文件非常大(巨大的模板!)。
只需在 A 类的标题中声明该类即可。
class B;
第二个更好。它使B
该类成为您使用该.h
文件包含的模块。考虑您B
将来子类化并更新A
为使用C
. 在第二种情况下,您只需更换标题#include
和A
化妆。在第一种情况下,您必须更改前向声明。此外,在第二种情况下,您定义的不仅仅是符号B
。
#include "B.h"
和注释一样,如果头文件与其余代码位于同一目录中,则应使用。
好吧,您正在做的事情称为前向减速,您想要这样做的原因是,如果您有类似使用 B 类的 A 类和使用 A 类的 B 类的东西。
在只有一个关系的情况下,您当然可以使用第二个选择。如果您需要双重使用,那么您的至少一个类 decleration 必须使用前向 decleration