打破循环引用在C++中更优雅

Breaking cyclic references more elegant in C++

本文关键字:C++ 循环 引用      更新时间:2023-10-16

当我的头文件相互包含时,我最近得到了许多循环依赖关系。 另请参阅此处:什么是C++中的前瞻声明?

我实际上并不完全理解为什么这是一个循环。当编译器查看包含的头文件内部时,为什么它无法识别类声明?

有没有更优雅/其他的方式来打破这些循环,而不是另一个类的前向声明?我不喜欢在我目前的班级面前有其他类声明。例如

#include "Wheel.h"  // Include Wheel's definition so it can be used in Car.
#include <vector>
class Wheel;
class Car
{
std::vector<Wheel> wheels;
};

我希望我明白了你的卡点。

为了解释这一点,最好从编译器的角度进行检查。

编译器为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

据我所知,有一个定义规则有额外的限制,也许其他人可能会解释这一点。

目前不可能有"更优雅"的方式。

Will 可以在每个文件中使用指令#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

在所有头文件中执行此操作,因此每个文件最多加载一次,并且循环将不再发生