C++ C++;相互标题包含和转发声明

C++ C++;相互标题包含和转发声明,c++,header-files,forward-declaration,C++,Header Files,Forward Declaration,如何允许两个类相互包含,以便它们可以从一个类转换为另一个类 Car.hpp #ifndef CAR_HPP #define CAR_HPP #include "Truck.hpp" class Car { public: Car(int weight) : weight(weight) {} Car(Truck data) : weight(ConvertFromTruck(data)) {} private: int weight; int ConvertF

如何允许两个类相互包含,以便它们可以从一个类转换为另一个类

Car.hpp

#ifndef CAR_HPP
#define CAR_HPP

#include "Truck.hpp"
class Car
{
public:
    Car(int weight) : weight(weight) {}
    Car(Truck data) : weight(ConvertFromTruck(data)) {}

private:
    int weight;
    int ConvertFromTruck(Truck data)
    {
        ... //in real life there would be a lot more to transfer than just weight.
    }
}
#endif //CAR_HPP
卡车.hpp

#ifndef TRUCK_HPP
#define TRUCK_HPP

#include "Car.hpp" //Obviously won't be included because of the CAR_HPP include guard
class Truck
{
public:
    Truck(int weight) : weight(weight) {}
    Truck(Car data) : weight(ConvertFromCar(data)) {}

private:
    int weight;
    int ConvertFromCar(Car data)
    {
        ...//in real life there would be a lot more than just weight
    }
}
#endif //TRUCK_HPP
Main.cpp

#include "Car.hpp"
#include "Truck.hpp"

int main()
{
    Car newCar(42);
    Truck newTruck(newCar);

    return 0;
}
所以很明显,Truck.hpp不能真正包括Car.hpp,因为Car_hpp已经定义好了。此外,Truck.hpp不能向前申报
级车辆因为
卡车(汽车数据)..
需要完整的类型,而向前声明的类不是完整的类型

这看起来很相似:但没有答案

本主题声明不包含相互包含标头

我会尽量避免这种情况,但我如何才能实现一辆能够接收并正确转换卡车的汽车,以及一辆能够接收并正确转换汽车的卡车

我有没有办法使用:
operator Car(){…}
operator Truck(){…}
以便将汽车铸造成卡车,反之亦然?

在声明中

int ConvertFromTruck(卡车数据)

Truck
需要是一个完整的类型,这意味着
Truck
的类定义必须可供编译器使用。这就是你的问题所在

幸运的是,有一个解决方案:通过
const
参考传递
卡车

int ConvertFromTruck(const Truck&data)

这里,编译器只需要
Truck
的一个不完整类型,一个转发类声明而不是
#include
就足够了。这在运行时也非常优越,因为当函数运行时,您没有获取
Truck
的值副本(尽管编译器可能会优化该副本)

对构造函数(即
Car(const Truck&data)
)和
Truck
类也执行同样的操作


请注意,我使用
const
引用而不是非
const
引用有两个原因(I)您不想修改传递的对象,以及(ii)匿名临时用户可以绑定到
const
引用。

改为使用引用(例如
Truck::Truck(Car&data)
)@Kevin:你会想要一份
const
参考资料的,真的,好几年没看过了。但我有更多的经验。我认为除了引用之外,这个类还需要向前声明。哦,太好了!它允许我做我想做的事情,通过引用传递更有效!令人惊叹的!谢谢对于(i)您说过我希望能够修改传递的对象。是否确实要修改传递的对象?康斯特不会把那个对象设为只读吗?@problem:Oops,漏掉了一个don't。没问题!我以为这就是你的意思,但检查一下也无妨。