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.
-
1maybe I misunderstood your question, but can't you just avoid the "virtual" word? – David Szalai Jun 20 '14 at 21:10
-
3Explicitely have no virtual class destructor declaration/definition! And may be even make it `protected`. – πάντα ῥεῖ Jun 20 '14 at 21:10
-
In my case I utterly need a virtual destructor in my class and I need to prevent it from being a virtual base class. Final keyword or private/protected constructor blocks the inheritance totally and that's not what I want – Victor Komarov Jun 20 '14 at 21:14
-
4OP wants to prohibit `struct C : virtual Base {};` – Jarod42 Jun 20 '14 at 21:19
-
1@VictorK What do you want then, that all sounds a bit contradictorily for me! Elaborate please why you _'In my case I utterly need a virtual destructor'_! – πάντα ῥεῖ Jun 20 '14 at 21:20
-
@πάντα ῥεῖ http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors – Victor Komarov Jun 20 '14 at 21:38
-
2Normally I'd ask why you want to do this, cause this smells like an X-Y problem. But in this case I'm really curious to know if this is possible. – Praetorian Jun 20 '14 at 21:48
-
@Praetorian Apparently it's not possible, as stated here: http://stackoverflow.com/questions/21558/in-c-what-is-a-virtual-base-class – πάντα ῥεῖ Jun 20 '14 at 22:23
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() {
}
};
-
If you have no virtual methods declared in your class it can't be inherited virtual - that's really something new – Victor Komarov Jun 20 '14 at 21:34
-
1This is wrong, a base class can not make a promise not being inherited virtual. – Jun 20 '14 at 21:34
-
-
@VictorK See my updates in the answer please! Seems you can't prevent an inheriting class specifying the `virtual` keyword at all, seems you've been confusing purpose of it may be ... – πάντα ῥεῖ Jun 20 '14 at 22:35
-
Virtual inheritance has nothing to do with virtual functions. Man, thank you for your time, but your answer is of no use unfortunately. – Victor Komarov Jun 21 '14 at 05:28
-
@VictorK I'm with praetorian's comment: _Smells like a xy-problem_. You should clarify in your question what you want to achieve finally. May be it's possible to show you a viable solution then. – πάντα ῥεῖ Jun 21 '14 at 09:16