【发布时间】:2022-01-23 00:17:25
【问题描述】:
我无法理解在多重继承情况下如何区分基类的多个实例。在寻找解决方案时,我只找到了关于 virtual inheritance 的答案,但这根本不能解决我的问题,因为我不想在继承树末尾的最终类中拥有单个基类实例。
在维基百科上,第一段指出:
如果没有虚拟继承,如果两个类 B 和 C 继承自类 A,而类 D 继承自 B 和 C,那么 D 将包含 A 的成员变量的两个副本:一个通过 B,一个通过 C。这些将可以使用范围解析独立访问。
但我没有找到任何关于如何在我的情况下使用范围解析的信息。
至于我的任务,(强制和过于复杂的)类层次结构是:
class Vehicle
{
protected:
unsigned long uPrice;
char* szOwner; // for some reason, not allowed to use std::string in my homework...
public:
unsigned long GetPrice();
// ...
}
class Trailer : public Vehicle
{
protected:
unsigned long uWid;
unsigned long uHei;
unsigned long uLen;
unsigned long uMaxWeight;
public:
// ...
};
class Car : public Vehicle
{
protected:
unsigned long uWid;
unsigned long uHei;
unsigned long uLen;
char* szBrand;
public:
// ...
};
class Trailer_Car : public Trailer, public Car
{
private:
unsigned long uTotalMass;
public:
// ...
};
如上所述,我希望Trailer_Car 的一个实例中有多个Vehicle 实例(一个用于Car,一个用于Trailer)。这完全适用于:
Trailer_Car c(/*...*/, 3500, 1200);
std::cout << c.Trailer_Car::Car::GetPrice() << "\n"; // prints 3500
std::cout << c.Trailer_Car::Trailer::GetPrice(); // prints 1200
但是,在我的代码中,我必须对一个不均匀的数组(可以包含 4 个类中的任何一个)进行排序,并将Trailer_Car 转换为Vehicle 会导致error: 'Vehicle' is an ambiguous base of 'Trailer_Car'。示例:
Vehicle** Arr = new Vehicle*[N];
// ...
Arr[i] = static_cast<Vehicle*>(new Trailer_Car); // error: 'Vehicle' is an ambiguous base of 'Trailer_Car'
我该如何解决这个问题?我知道错误来自这样一个事实,即Arr[i] 不知道从Trailer_Car 指向哪个Vehicle,但仍然没有想到C++。
由于我更习惯于 C,所以我只会将 Arr 设为 void**,尽管我不知道 C++ 中的做法有多好,我要求这样做以避免在 C++ 中使用 C。
【问题讨论】:
-
为什么不希望在继承树末尾的最终类中拥有单个基类实例?
Trailer_Car派生自 2 个基本Vehicle类是什么意思? -
@drescherjm 遗憾的是,没有,虚拟继承将生成基类的单个实例,我需要两个(一个存储预告片的价格和所有者,一个存储价格和所有者汽车)
-
您确实意识到,如果没有虚拟析构函数,您将无法正确释放任何继承自
Vehicle的类,仅给出指向Vehicle的指针。Trailer_Car的一个更“自然”的替代方案是CombinedVehicle拥有 2 辆(甚至更多)车辆并使用这些来确定它所代表的车辆的属性(例如,使用零件价格的总和作为总和等)。至于访问权限:您可以向上转换到不再模棱两可的程度,但正如所说的那样,这不是一个好主意Arr[i] = static_cast<Trailer*>(new Trailer_Car); -
@fabian 是的,我知道,我永远不会设计这样的课程,但功课就是功课 :( 我不能随意修改课程。
标签: c++ inheritance