Implementation of interface in C++

1.2k Views Asked by At

I need little help with inheritance in C++. I have code with same structure like this:

class IBase {
public:
    virtual long Dimensions() = 0;
};

class IShape : public IBase {
    virtual long Area() = 0;
};

class Rectangle : public IShape  {
private:
    long x;
public:
    long Dimensions() {return x};
    long Area() {return x*x};
};

class Rhombus: public IShape  {
private:
    long x;
    long fi;
public:
    long Dimensions() {return x};
    long Area() {return x*x*sin(fi)};
};

As you can see, implementation of Dimensions() is same for both classes. Now I wan't to do something like this:

class BaseImplementation : public IBase {
protected:
    long x;
public:
    virtual long Dimensions() {return x};
};

class Rectangle : public IShape, public BaseImplementation {
public:
    long Area() {return x*x};
};

class Rhombus: public IShape, public BaseImplementation {
private:
    long fi;
public:
    long Area() {return x*x*sin(fi)};
};

Is possible to insert implementation of method Dimensions() into class Rhombus from BaseImplementation? Is this supported in some version of C++ standard? Thx.

4

There are 4 best solutions below

0
On BEST ANSWER

The problem with your hierarchy is that your Rectangle now inherits IBase twice: once through IShape, and once through BaseImplementation. C++ feature called Virtual Inheritance is designed to deal with situations like that. Note that you need to make IShape's inheriting IBase virtual public as well.

1
On

If Dimensions() is implemented in BaseImplementation, and is at least protected in access, it should be visible to any derived object.

So Rhombus will be able to use the Dimension() function if it is derived from BaseImplementation. If you want to have a specific implementation for Dimension() in case of a Rhombus, your Dimension() should be virtual and you should override it in Rhombus

0
On

There is no need to explicitly insert the implementation. You can already call myRhombus->Dimension() because it is inherited.

0
On

You could simply implement a layer in between that defines Dimension:

class IBase {
public:
    virtual long Dimensions() = 0;
};

class IShape : public IBase {
public:
    virtual long Area() = 0;
};

class IShapesDefinedDimension : public IShape
{
public:
   long Dimensions() { return x; }
protected:
    long x;
};

class Rectangle : public IShapesDefinedDimension  {
public:
    long Area() {return x*x;}
};

class Rhombus: public IShapesDefinedDimension  {
public:
    long Area() {return x*x*sin(fi); }
...
    };