I would like to use interfaces in c++ like in java or in c#. I decided to use purely abstract classes with multiple inheritance, but something is terribly wrong when I specialize the interface:
class Interface
{
public:
virtual int method() = 0;
};
// Default implementation.
class Base: virtual public Interface
{
public:
virtual int method() {return 27;}
};
// specialized interface
class Interface2: public Interface
{
public:
virtual int method() = 0;
// some other methods here
};
// concrete class - not specialised - OK
class Class: public virtual Interface, public virtual Base
{
};
// concrete class - specialised
class Class2: public Interface2, public Base
{
};
int main()
{
Class c;
Class2 c2;
return 0;
}
Warning 1 warning C4250: 'Class' : inherits 'Base::Base::method' via dominance 30
Error 2 error C2259: 'Class2' : cannot instantiate abstract class 42
What is the proper way to do this?
You use an interface to define a protocol of behavior that can be implemented by any class anywhere in the class hierarchy. Interfaces are useful for the following: Capturing similarities among unrelated classes without artificially forcing a class relationship.
In English, an interface is a device or system that unrelated entities use to interact.
graphical user interface (GUI) command line interface (CLI) menu-driven user interface. touch user interface.
There are three main interface connections: the memory/IO interface, interrupt interface and DMA (direct memory access) interface. Figure 14.2. Some of the 80386/80486 signal connections.
Class2 inherits from an abstract class (Interface2) but does not implement the pure virtual method, so it remains as an abstract class.
Heh heh, this problem tickles something buried deep in my head somewhere. I can't quite put my finger on it but I think it's to do with defining an interface heirarchy and then inheriting both an interface and an implementation. You then avoid having to implement all functions with by forwarding calls to a base class. I think.
I think this simple example shows the same thing, but is maybe a bit easier to understand because it uses things that can be easily visualized: (please forgive the struct laziness)
#include <iostream>
using namespace std;
struct Vehicle
{
virtual void Drive() = 0;
};
struct VehicleImp : virtual public Vehicle
{
virtual void Drive()
{
cout << "VehicleImp::Drive\n";
}
};
struct Tank : virtual public Vehicle
{
virtual void RotateTurret() = 0;
};
struct TankImp : public Tank, public VehicleImp
{
virtual void RotateTurret()
{
cout << "TankImp::RotateTurret\n";
}
// Could override Drive if we wanted
};
int _tmain(int argc, _TCHAR* argv[])
{
TankImp myTank;
myTank.Drive(); // VehicleImp::Drive
myTank.RotateTurret(); // TankImp::RotateTurret
return 0;
}
TankImp has essentially inherited the Tank interface and the Vehicle implementation.
Now, I'm pretty sure this is a well known and acceptable thing in OO circles (but I don't know if it has a fancy name), so the dreaded diamond thing is ok in this case, and you can safely suppress the dominance warning because it's what you want to happen in this case.
Hope that somehow helps point you in the right direction!
BTW, your code didn't compile because you hadn't implemented the pure virtual "method" in Class2.
EDIT:
Ok I think I understand your problem better now and I think the mistake is in Interface2. Try changing it to this:
// specialized interface
class Interface2: public virtual Interface // ADDED VIRTUAL
{
public:
//virtual int method() = 0; COMMENTED THIS OUT
// some other methods here
};
Interface2 should not have the pure virtual defintion of method, since that is already in Interface.
The inheritance of Interface needs to be virtual otherwise you will have an ambiguity with Base::method when you derive from Interface2 and Base in Class2.
Now you should find it will compile, possibly with dominance warnings, and when you call c2.method(), you get 27.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With