Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interfaces in c++

Tags:

c++

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?

like image 781
danatel Avatar asked Apr 30 '09 12:04

danatel


People also ask

What interfaces are used for?

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.

What is a interface?

In English, an interface is a device or system that unrelated entities use to interact.

What are interface types?

graphical user interface (GUI) command line interface (CLI) menu-driven user interface. touch user interface.

What are the main interfaces?

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.


2 Answers

Class2 inherits from an abstract class (Interface2) but does not implement the pure virtual method, so it remains as an abstract class.

like image 100
Tom Avatar answered Oct 06 '22 00:10

Tom


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.

like image 24
markh44 Avatar answered Oct 05 '22 23:10

markh44