我有一个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_;
};
哪种方式更好,当一个没有太多依赖的小项目涉及时,这两个是相似的吗?
答案 0 :(得分:31)
您执行此操作的第一种方式意味着在a.h
中,class B
的存在是已知的,而不是定义。这限制了您在B
内使用a.h
可以执行的操作。例如,您可以使用B *
类型的变量,但不能使用B
类型的变量(因为对于类型为B
的变量的声明,编译器必须能够看到完整定义B
)。此外,如果您有B *
类型的变量,则无法取消引用指针(因为也必须知道B
的定义)。
因此,您的第二选择 - 没有这些问题 - 是首选,这是大多数人在大多数时间使用的。
只有第一种方法可能有用的特殊情况。例如:
.h
文件包含彼此(但是您可能会遇到一些其他问题,也可能涉及包含警示;这通常很难并且应该避免); < / LI>
b.h
非常庞大且复杂,那么您希望尽可能避免将其包含在内,因为它会降低编译过程的速度。答案 1 :(得分:16)
您的第一种方法是前瞻性声明。你的第二个实际上包括B类。
何时使用其中一个?
答案 2 :(得分:11)
答案: 1 。
看看http://www.umich.edu/~eecs381/handouts/handouts.html
C Header File Guidelines
C++ Header File Guidelines(密歇根大学EECS部门David Kieras)说:
准则#10。 如果类型X的声明不完整,请使用 它不是#including其标题X.h 。如果是另一个结构或类 类型X仅在内容中显示为指针或引用类型 一个标题文件,那么你不应该#include X.h,而只是放置一个 不完整的X声明(也称为“前进”声明)附近 标题文件的开头,如:
class X;
请参阅讲义 Incomplete Declarations有关这个强大的和更多的讨论 宝贵的技术。请注意,标准库包含标头 不完整的声明通常会对<iostream>
产生影响 库,名为<iosfwd>
。尽可能#include<iosfwd>
,因为<iostream>
标题文件非常大(巨型模板!)。
答案 3 :(得分:0)
只需在班级A的标题中声明该课程。
class B;
答案 4 :(得分:0)
第二个更好。它使B
类成为您使用.h
文件包含的模块。考虑将来继承B
的情况,并更新A
以使用C
。在第二种情况下,您只需替换标题#include
和A
的化妆。在第一种情况下,您必须更改前向声明。此外,在第二种情况下,您定义的不仅仅是符号B
。
如同评论中一样,如果头文件与其余代码位于同一目录中,则应使用#include "B.h"
。
答案 5 :(得分:0)
你正在做的事情被称为前向解除,你想要的原因就是如果你有类似A的东西使用B类而ALSO B类使用A类。
如果只有一种关系,你当然可以使用你的第二选择。 如果你需要双重用法,那么至少你的一个类别的declerations将不得不使用前进的decleration