Your use of virtual
inheritance here is spurrious, and is a red herring. virtual
inheritance is used to derive from common base classes only once; not to bring in only one declaration for matching member signatuires.
So, your FastCar
concrete class actually has 3 members, not 2:
virtual void ICar::drive()
virtual void IFastCar::drive()
virtual void IFastCar::driveFast()
The two different drive()
appear to be related, so your design appears to be flawed. You don't want virtual
inheritance -- you probably want IFastCar
to derive from 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;
}
If you then wanted Car
to implement some basic functionality that FastCar
will employ, then you can derive FastCar
from Car
, and that is why you would want virtual
inheritance. Just remember to apply virtual
inheritance at the point just below the top of the diamond:
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;
}
If you compile & run the above code you will get the desired behavior, but at the cost of a compiler warning. On MSVC10 it reads:
1>main.cpp(19): warning C4250: 'FastCar' : inherits 'Car::Car::drive' via dominance
1> main.cpp(13) : see declaration of 'Car::drive'
This is a warning that your implementation inheritance architecture might be screwed up. And in fact, in most cases it probably is (although in this case not). This can get awful confusing real fast, especially to a maintenance programmer years from now trying to figure out your code. To clear up this confusion and avoid all the compiler warnings, I much prefer (as a rule) delegation to a sister class rather than implementation inheritance.
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;
}
This accomplishes the usual goal of implementation inheritance -- keeping just one common set of code that can be shared across multiple concrete classes, making maintenance easier.