Reputation: 231
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
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 Rectangle
s have length and width. Only Ellipse
s 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
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