user3697176
user3697176

Reputation: 231

Pure virtual functions and multiple inheritance

I have a (guaranteed tree-shaped) cascade of classes like

class rock_bottom {
    ...
    virtual foo() = 0;
};

class A : rock_bottom {...}

class intermediate: rock_bottom {...}   

class B : intermediate {...}

class higher_up {...}

class C : higher_up {...}

I want to implement foo() in the lettered classes A, B, C. Where do I need to declare foo? (Virtual? Pure?) Do I need (trivial) implementations in the middle layers intermediate and higher_up?

Upvotes: 0

Views: 689

Answers (2)

R Sahu
R Sahu

Reputation: 206607

Question:

I want to implement foo() in the lettered classes A, B, C. Where do I need to declare foo? (Virtual? Pure?)

Answer:

That question needs to be asked in reverse. In which base class does it make sense to create the interface foo. Let's take some classes that you might find in application.

struct Shape {};
struct Rectangle : public Shape {};
struct Square : public Rectangle {};
struct Ellipse : public Shape {};
struct Circle : public Ellipse {};

It makes sense that all Shape be able to return their area and perimeter. So you put them as virtual member functions in Shape.

struct Shape 
{
   virtual double area() const = 0;
   virtual double perimeter() const = 0;
};

Before you can create an instance of sub-type of Shape, you must implement them.

If you want to be able to create a Rectangle, those functions must be implemented in Rectangle since there are no other intermediate classes.

If you want to be able to create a Square, those functions must be implemented either in Rectangle, Square, or both.

Similarly, if you want to be able to create a Ellipse, those functions must be implemented in Ellipse since there are no other intermediate classes.

If you want to be able to create a Circle, those functions must be implemented either in Ellipse, Circle, or both.

However, only Rectangles have length and width. Only Ellipses have major radius and minor radius. It doesn't make sense to add virtual member functions in Shape to return those values.

Question:

Do I need (trivial) implementations in the middle layers intermediate and higher_up?

Answer:

No, you don't. The answer to the previous question should clarify that more.

Upvotes: 2

Mike Seymour
Mike Seymour

Reputation: 254471

Each override needs to be declared in the class that implements it; in your case, A, B and C, since you say each will provide an override.

There's no need to declare it in any intermediate class, assuming you're happy for them to remain abstract. They inherit the pure function from rock_bottom, and there's no point overriding that with another pure function.

Upvotes: 1

Related Questions