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.
Virtual inheritance is a C++ technique that ensures only one copy of a base class's member variables are inherited by grandchild derived classes.
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).
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.
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.
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() {
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With