【发布时间】:2009-12-03 01:49:42
【问题描述】:
所以我有一个 A 类,我想在其中调用一些 B 类函数。所以我包括“b.h”。但是,在 B 类中,我想调用 A 类函数。如果我包含“a.h”,它最终会进入无限循环,对吗?我该怎么办?
【问题讨论】:
标签: c++ class include forward-declaration
所以我有一个 A 类,我想在其中调用一些 B 类函数。所以我包括“b.h”。但是,在 B 类中,我想调用 A 类函数。如果我包含“a.h”,它最终会进入无限循环,对吗?我该怎么办?
【问题讨论】:
标签: c++ class include forward-declaration
仅将成员函数声明放在头文件 (.h) 中,并将成员函数定义放在实现 (.cpp) 文件中。那么你的头文件不需要相互包含,你可以在任一实现文件中包含两个头文件。
如果您还需要在成员签名中引用其他类,您可以使用前向声明:
class A;
这允许您使用指针和引用类型(A* 和 A&),但不能使用 A 本身。它也不允许您呼叫成员。
例子:
// a.h
struct B; // forward declaration
struct A {
void foo(B* b); // pointers and references to forward-declared classes are ok
};
// b.h
struct A; // forward declaration
struct B {
void bar(A& a); // pointers and references to forward-declared classes are ok
};
// a.cpp
#include "a.h"
#include "b.h"
void A::foo(B* b) {
b->bar(*this); // full declaration of B visible, ok to call members now
}
// b.cpp
#include "a.h"
#include "b.h"
void B::bar(A& a) {
a.foo(this); // full declaration of A visible, ok to call members now
}
【讨论】:
每个类(A 和 B)都应该有一个头文件和一个实现文件。
每个头文件(例如A.h)不应包含另一个头文件(例如B.h),但可以包含对另一个类的前向引用(例如class B;之类的语句),然后可以使用指针和/或在其声明中引用其他类(例如,class A 可能包含 B* 作为数据成员和/或作为方法参数)。
每个 CPP 文件(例如 A.cpp)可能包含多个头文件(例如 A.h 和 B.h)。建议每个 CPP 文件应首先包含自己的头文件(例如,A.cpp 应包含 A.h,然后是 B.h,而 B.cpp 应包含 B.h,然后是 A.h)。
每个头文件应该只包含声明,而不是类的定义:例如,它将列出类方法的签名,但不包含方法体/实现(方法体/实现将在.cpp 文件,不在头文件中)。由于头文件不包含实现细节,因此它们不依赖(不需要查看)其他类的细节;最多他们需要知道,例如,B 是一个类的名称:它可以从前向声明中获取,而不是通过在另一个头文件中包含一个头文件。
【讨论】:
您也可以使用forward declarations 来解决此问题。
【讨论】:
尝试将#ifndef、#define 和#endif 放在您的.h 文件周围。
【讨论】: