简体   繁体   中英

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?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM