在 C++ 中更优雅地打破循环引用
Breaking cyclic references more elegant in C++
最近当我的头文件相互包含时,我得到了很多循环依赖。
另见此处:What are forward declarations in C++?
我其实完全不明白为什么它是一个循环。当编译器查看 include 的头文件时,为什么它不识别 class 声明?
是否有更多 elegant/other 方法来打破这些循环,而不是另一种 class 的前向声明?我不喜欢在我当前的 class 前面还有另一个 class 声明。例如
#include "Wheel.h" // Include Wheel's definition so it can be used in Car.
#include <vector>
class Wheel;
class Car
{
std::vector<Wheel> wheels;
};
将可以在每个文件中使用指令 #ifndef
... #define
#endif
所以你的代码会变成
#ifndef CAR_H
#define CAR_H
#include "Wheel.h" // Include Wheel's definition so it can be used in Car.
#include <vector>
class Car
{
std::vector<Wheel> wheels;
};
#endif
在你所有的头文件中这样做,这样每个文件最多加载一次并且循环不会再发生
希望我能理解你的难点。
要说明这一点,最好从编译器的角度来考察。
编译器为 Car.h
:
- 用其内容替换
#include "Wheel.h"
。
- 用其内容替换
#include <vector>
。
在这一步,Car.h
的翻译单元是这样的。
class Car;
class Wheel
{
Car* car;
};
// Vector implementation of the stl goes here
class Car
{
std::vector<Wheel> wheels;
};
此时,在Car* car;
行,需要class Car
声明(指针类型的声明就足够了)来定义class Wheel
这就是为什么你需要前向声明,因为你应该告诉编译器有一个 class Car
并且很快就会被定义。
如果您在第 1 行注释掉 class Car
,编译器将无法知道是否会有 class Car
。
据我所知,一个定义规则有额外的限制,也许其他人可能会解释一下。
目前无法'more elegant'方式。
最近当我的头文件相互包含时,我得到了很多循环依赖。 另见此处:What are forward declarations in C++?
我其实完全不明白为什么它是一个循环。当编译器查看 include 的头文件时,为什么它不识别 class 声明?
是否有更多 elegant/other 方法来打破这些循环,而不是另一种 class 的前向声明?我不喜欢在我当前的 class 前面还有另一个 class 声明。例如
#include "Wheel.h" // Include Wheel's definition so it can be used in Car.
#include <vector>
class Wheel;
class Car
{
std::vector<Wheel> wheels;
};
将可以在每个文件中使用指令 #ifndef
... #define
#endif
所以你的代码会变成
#ifndef CAR_H
#define CAR_H
#include "Wheel.h" // Include Wheel's definition so it can be used in Car.
#include <vector>
class Car
{
std::vector<Wheel> wheels;
};
#endif
在你所有的头文件中这样做,这样每个文件最多加载一次并且循环不会再发生
希望我能理解你的难点。
要说明这一点,最好从编译器的角度来考察。
编译器为 Car.h
:
- 用其内容替换
#include "Wheel.h"
。 - 用其内容替换
#include <vector>
。
在这一步,Car.h
的翻译单元是这样的。
class Car;
class Wheel
{
Car* car;
};
// Vector implementation of the stl goes here
class Car
{
std::vector<Wheel> wheels;
};
此时,在Car* car;
行,需要class Car
声明(指针类型的声明就足够了)来定义class Wheel
这就是为什么你需要前向声明,因为你应该告诉编译器有一个 class Car
并且很快就会被定义。
如果您在第 1 行注释掉 class Car
,编译器将无法知道是否会有 class Car
。
据我所知,一个定义规则有额外的限制,也许其他人可能会解释一下。
目前无法'more elegant'方式。