您virtual
在这里使用继承是虚假的,并且是转移注意力。 virtual
继承仅用于从公共基类派生一次;不要只为匹配的成员签名引入一份声明。
因此,您的FastCar
具体类实际上有 3 个成员,而不是 2 个:
virtual void ICar::drive()
virtual void IFastCar::drive()
virtual void IFastCar::driveFast()
这两个不同drive()
似乎是相关的,所以你的设计似乎有缺陷。您不想要virtual
继承——您可能想要IFastCar
从ICar
.
class ICar {
public:
virtual void drive() = 0;
};
class IFastCar : public ICar {
public:
virtual void driveFast() = 0;
};
class Car : public virtual ICar {
public:
void drive() {};
};
class FastCar : public IFastCar {
public:
void drive() {};
void driveFast() {};
};
int main()
{
FastCar fc;
fc.drive();
fc.driveFast();
return 0;
}
如果您想Car
实现一些FastCar
将使用的基本功能,那么您可以从 派生FastCar
,Car
这就是您想要virtual
继承的原因。请记住virtual
在钻石顶部正下方的点应用继承:
class ICar {
public:
virtual void drive() = 0;
};
class IFastCar : virtual public ICar {
public:
virtual void driveFast() = 0;
};
class Car : public virtual ICar {
public:
void drive() {};
};
class FastCar : public IFastCar, public Car {
public:
void driveFast() {};
};
int main()
{
FastCar fc;
fc.drive();
fc.driveFast();
ICar* fc_a = new FastCar;
fc_a->drive(); // invokes Car::drive() via domination
return 0;
}
如果您编译并运行上述代码,您将获得所需的行为,但代价是编译器警告。在 MSVC10 上显示:
1>main.cpp(19): warning C4250: 'FastCar' : inherits 'Car::Car::drive' via dominance
1> main.cpp(13) : see declaration of 'Car::drive'
这是一个警告,您的实现继承架构可能被搞砸了。事实上,在大多数情况下它可能是(尽管在这种情况下不是)。这可能会很快变得非常混乱,特别是对于多年后试图找出您的代码的维护程序员来说。为了消除这种混淆并避免所有编译器警告,我更喜欢(通常)委派给姊妹类而不是实现继承。
class ICar {
public:
virtual void drive() = 0;
};
class IFastCar : virtual public ICar {
public:
virtual void driveFast() = 0;
};
class ICarImpl
{
public:
void drive_impl() {};
};
class IFastCarImpl
{
public :
void driveFast_impl() {};
};
class Car : public virtual ICar, protected ICarImpl {
public:
void drive() { drive_impl(); }
};
class FastCar : public IFastCar, protected ICarImpl, protected IFastCarImpl {
public:
void driveFast() { driveFast_impl(); }
void drive() { drive_impl(); }
};
int main()
{
FastCar fc;
fc.drive();
fc.driveFast();
ICar* fc_a = new FastCar;
fc_a->drive();
return 0;
}
这实现了实现继承的通常目标——只保留一组可以在多个具体类之间共享的通用代码,从而使维护更容易。