Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blocking virtual inheritance

Is there a way in modern C++ to prevent a class from being virtually inherited, while allowing regular inheritance at the same time? Right now it seems impossible to me, but there were too many things in this language that seemed impossible.

like image 378
Victor Komarov Avatar asked Jun 20 '14 21:06

Victor Komarov


People also ask

What is meant by virtual inheritance?

Virtual inheritance is a C++ technique that ensures only one copy of a base class's member variables are inherited by grandchild derived classes.

What is virtual inheritance good for?

Virtual inheritance is used when we are dealing with multiple inheritance but want to prevent multiple instances of same class appearing in inheritance hierarchy. From above example we can see that “A” is inherited two times in D means an object of class “D” will contain two attributes of “a” (D::C::a and D::B::a).

Can virtual methods be inherited?

Base classes can't inherit what the child has (such as a new function or variable). Virtual functions are simply functions that can be overridden by the child class if the that child class changes the implementation of the virtual function so that the base virtual function isn't called. A is the base class for B,C,D.

How do you stop inheritance in C++?

The concept of preventing the inheritance is known as final class. In Java or C#, we can use final classes. In C++ there are no such direct way.


1 Answers

The purpose of the virtual keyword specified for an inherited base is to prevent it to occur instantiated multiple times in an inheritance hierarchy. So usage of this can't prevented in first place (see also 'What is a virtual base class').
I believe you may have confused what are your possibilities how to control what actually can be overidden by inheriting classes.

If you have no virtual methods declared in your class an inheriting class can't provide any virtual overrides for any methods from that base.
Best to state this semantically in first place is

class Foo {
public:
    Foo() {}
protected:
    ~Foo() {} // Explicitly non virtual destructor, prevents virtual inheritance
              // 'protected' forces inheritance to use this class
};

Even using introduced pure abstract interfaces this should work well

struct IFace {
     virtual void some_operation() = 0;
     virtual ~IFace() {}
}; 

class Foo : public IFace {
public:
     // Implementation of interface methods
     virtual void some_operation() { 
     }

    // Same as above. Possibility of virtual inheritance stops here
};

UPDATE:
Seems that @DieterLücking's comment and your online code sample disprove what I said. That obviously doesn't stop from using the virtual keyword for inheritance in 1st place, and it seems there's nothing you can do against it.

Though you can prevent inheriting classes to (re-)implement interfaces simply by providing these implementations as private then:

class Foo : public IFace {
private:
     // Implementation of interface methods
     virtual void some_operation() { 
     }
};
like image 154
πάντα ῥεῖ Avatar answered Sep 30 '22 17:09

πάντα ῥεῖ