If I have a base class with a virtual destructor. Has a derived class to declare a virtual destructor too?
class base {
public:
virtual ~base () {}
};
class derived : base {
public:
virtual ~derived () {} // 1)
~derived () {} // 2)
};
Concrete questions:
Is 1) and 2) the same? Is 2) automatically virtual because of its base or does it "stop" the virtualness?
Can the derived destructor be omitted if it has nothing to do?
What's the best practice for declaring the derived destructor? Declare it virtual, non-virtual or omit it if possible?
Yes, they are the same. The derived class not declaring something virtual does not stop it from being virtual. There is, in fact, no way to stop any method (destructor included) from being virtual in a derived class if it was virtual in a base class. In >=C++11 you can use final to prevent it from being overridden in derived classes, but that doesn't prevent it from being virtual.
Yes, a destructor in a derived class can be omitted if it has nothing to do. And it doesn't matter whether or not its virtual.
I would omit it if possible. And I always use either the virtual keyword or override for virtual functions in derived classes for reasons of clarity. People shouldn't have to go all the way up the inheritance hierarchy to figure out that a function is virtual. Additionally, if your class is copyable or movable without having to declare your own copy or move constructors, declaring a destructor of any kind (even if you define it as default) will force you to declare the copy and move constructors and assignment operators if you want them as the compiler will no longer put them in for you.
As a small point for item 3. It has been pointed out in comments that if a destructor is undeclared the compiler generates a default one (that is still virtual). And that default one is an inline function.
Inline functions potentially expose more of your program to changes in other parts of your program and make binary compatibility for shared libraries tricky. Also, the increased coupling can result in a lot of recompilation in the face of certain kinds of changes. For example, if you decide you really do want an implementation for your virtual destructor then every piece of code that called it will need to be recompiled. Whereas if you had declared it in the class body and then defined it empty in a .cpp file you would be fine changing it without recompiling.
My personal choice would still be to omit it when possible. In my opinion it clutters up the code, and the compiler can sometimes do slightly more efficient things with a default implementation over an empty one. But there are constraints you may be under that make that a poor choice.
The destructor is automatically virtual, as with all methods. You can't stop a method from being virtual in C++ (if it has already been declared virtual, that is, i.e. there's no equivalent of 'final' in Java)
Yes it can be omitted.
I would declare a virtual destructor if I intend for this class to be subclassed, no matter if it's subclassing another class or not, I also prefer to keep declaring methods virtual, even though it's not needed. This will keep subclasses working, should you ever decide to remove the inheritance. But I suppose this is just a matter of style.
A virtual member function will make implicitely any overloading of this function virtual.
So the virtual in 1) is "optional", the base class destructor being virtual makes all child destructors virtual too.
1/ Yes
2/ Yes, it will be generated by the compiler
3/ The choice between declaring it virtual or not should follow your convention for overriden virtual members -- IMHO, there are good arguments both way, just choose one and follow it.
I'd omit it if possible, but there is one thing which may incite you to declare it: if you use the compiler generated one, it is implicitly inline. There are time when you want to avoid inline members (dynamic libraries for instance).
Virtual functions are overridden implicitly. When the method of a child class matches the method signature of the virtual function from a base class, it is overridden.
This is easy to confuse and possibly break during refactoring, so there are override and final keywords since C++11 to mark this behavior explicitly. There is a corresponding warnings that forbid the silent behavior, for example -Wsuggest-override in GCC.
There is a related question for override and final keywords on SO: Is the 'override' keyword just a check for a overridden virtual method?.
And the documentation in the cpp reference https://en.cppreference.com/w/cpp/language/override
Whether to use override keyword with the destructors is still a bit of debate. For example see discussion in this related SO question: default override of virtual destructor
The issue is, that the semantics of the virtual destructor is different to normal functions. Destructors are chained, so all base classes destructors are called after child one. However, in case of a regular method base implementations of the overridden method are not called by default. They can be called manually when needed.
Related
Is there any reason to declare a method virtual if a class has no subclasses, and is always used directly?
For example:
class Foo {
public:
virtual void DoBar {
// Do something here.
}
}
I came across this in some code I was reading, and couldn't find any justification.
Thanks!
Well the essence of virtual keyword is directly related to inheritance. This is an extract from CPP Ref:-
Virtual members A virtual member is a member function that can be
redefined in a derived class, while preserving its calling properties
through references. The syntax for a function to become virtual is to
precede its declaration with the virtual keyword
So IMHO - the ans to your question is no - it makes no sense - unless the code has changed from initial implementation - and trust me that happens a lot!
It is useful when writing library code to keep the future programmer in mind who may want to extend the class and provide their own behaviour. For example it is common to have a virtual Paint() function or virtual mouse handling functions in GUI libraries. They provide default implementations, but they allow the possibility of extension.
If that class is meant to be derive from then yes it makes sense. These decisions should be made when deciding the architecture of a program, and defining what can be done with the interfaces. If they do not want this to be derived from then it should not be virtual. If they do want it to be derived from then it should be virtual (and it should also make the destructor virtual).
This question already has answers here:
virtual qualifier in derived class
(4 answers)
Closed 7 years ago.
Quite often I see code (e.g. here) where the override is also declared virtual even if the class is not meant to be subclassed again. E.g.
class A {
virtual void foo();
}
class B : public A {
virtual void foo();
}
// there is no subclass of B (and most likely there will never be one)
In my naive C++ beginners thinking, I find it much clearer and more explicit not to declare B::foo virtual in case it is not meant to be overridden. I.e.
class B : public A {
void foo();
}
Many methods I write are not meant to be overridden. On the other hand I understand virtual as indication that the method was designed to be overridden. I guess it is just a matter of taste, however I am not 100% sure:
Does it make any difference if B::foo() is declared virtual (assuming B will not be used as base class)?
There is no requirement to mark an overriden virtual method virtual in a derived class. The decision whether a method is virtual or not is made in the least derived class.
It is, however, a good idea to mark a virtual method explicitly virtual in a derived class for two reasons:
It serves as documentation for future readers of your code. That could be you, so this should be a strong incentive.
If someone decides to remove the virtual qualifier in the base class, a compiler can catch the bug before the application ships, and issue a warning. There is no requirement for a particular implementation to issue a diagnostic in this case, though.
If your compiler supports C++11, using the override specifier in derived classes is recommended, as it performs additional validation. It is required for an implementation to issue an error, if a base class method is not declared virtual, but the derived class uses an override specifier.
No, it doesn't make any difference. If A::foo is declared as virtual in the base class, B::foo is also virtual: whether you declare it as such or not.
A method doesn't lose is virtual qualifier, so if A::foo() is virtual, B::foo() is also virtual even without repeating the keyword in B::foo() declaration.
Before override, it may be a style to repeat virtual in derived classes to remember that it is a overridden method, now we can use override instead (and compiler check that it is correct whereas it can't do it simply with virtual)
Many methods I write are not meant to be overridden
So you may mark them as final to forbid the method to be overridden (you may also mark the class final if it makes sense).
Normally calling virtual functions from constructors is considered bad practice, because overridden functions in sub-objects will not be called as the objects have not been constructed yet.
But, Consider the following classes:
class base
{
public:
base() {}
~base() {}
private:
virtual void startFSM() = 0;
};
class derived final : public base
, public fsm_action_interface
{
public:
derived() : base{}
, theFSM_{}
{ startFSM(); }
/// FSM interface actions
private:
virtual void startFSM()
{ theFSM_.start(); }
private:
SomeFSMType theFSM_;
}
In this case class derived is marked as final so no o further sub-objects can exist. Ergo the virtual call will resolve correctly (to the most derived type).
Is it still considered bad practice?
This would still be considered bad practice as this sort of this almost always indicates bad design. You'd have to comment the heck out of the code to explain why this works in this one case.
T.C.'s comment above reinforces one of the reasons why this is considered bad practice.
What happens if, a year down the line, you decide that derived
shouldn't be final after all?
That said, in the example above, the pattern will work without issue. This is because the constructor of the most derived type is the one calling the virtual function. This problem manifests itself when a base class's constructor calls a virtual function that resolves to a subtype's implementation. In C++, such a function won't get called, because during base class construction, such calls will never go to a more derived class than that of the currently executing constructor or destructor. In essence, you end up with behavior you didn't expect.
Edit:
All (correct/non-buggy) C++ implementations have to call the version of the function defined at the level of the hierarchy in the current constructor and no further.
The C++ FAQ Lite covers this in section 23.7 in pretty good detail.
Scott Meyers also weighs in on the general issue of calling virtual functions from constructors and destructors in Effective C++ Item 9
Regarding
” Normally calling virtual functions from constructors is considered bad practice, because overridden functions in sub-objects will not be called as the objects have not been constructed yet.
That is not the case. Among competent C++ programmers it’s normally not regarded as bad practice to call virtual functions (except pure virtual ones) from constructors, because C++ is designed to handle that well. In contrast to languages like Java and C#, where it might result in a call to a method on an as yet uninitialized derived class sub-object.
Note that the dynamic adjustment of dynamic type has a runtime cost.
In a language oriented towards ultimate efficiency, with "you don't pay for what you don't use" as a main guiding principle, that means that it's an important and very much intentional feature, not an arbitrary choice. It's there for one purpose only. Namely to support those calls.
Regarding
” In this case class derived is marked as final so no o further sub-objects can exist. Ergo the virtual call will resolve correctly (to the most derived type).
The C++ standard guarantees that at the time of construction execution for a class T, the dynamic type is T.
Thus there was no problem about resolving to incorrect type, in the first place.
Regarding
” Is it still considered bad practice?
It is indeed bad practice to declare a member function virtual in a final class, because that’s meaningless. The “still” is not very meaningful either.
Sorry, I didn't see that the virtual member function was inherited as such.
Best practice for marking a member function as an override or implementation of pure virtual, is to use the keyword override, not to mark it as virtual.
Thus:
void startFSM() override
{ theFSM_.start(); }
This ensures a compilation error if it is not an override/implementation.
It can work, but why does startFSM() need to be virtual? In no case do you actually want to actually call anything but derived::startFSM(), so why have any dynamic binding at all? If you want to have it call the same thing as a dynamically binded method, make another non-virtual function called startFSM_impl() and have both the constructor and startFSM() call it instead.
Always prefer non-virtual to virtual if you can help it.
Diving back into the world of C++, and experimenting with interfaces. I can find plenty of online examples, but 99% of them are trivial 'all-in-one-file'.
Interfaces can be classified into 3 basic types- interfaces where (all|some|zero) functions must be overridden in a concrete subclass (all|some|zero pure virtual functions in c++ parlance).
Is it possible to implement any of the 3 in a single header file? (no .cpp twin) Why/why not? How? If not, what are my options for the .h/.cpp pair?
Some of the options I have seen are: virtual destructor, protected destructor, inline destructor, pure virtual destructor with an implementation,... my head is spinning!
EDIT: meant pure virtual, not virtual void
If you make your interface pure virtual, the compiler will give an error if you forget to implement a method in your concrete class.
If there are methods that have some sane default implementation you can provide it, but this is just a convenience.
If you make the destructor virtual, you can delete the object via its interface pointer rather than requiring the concrete object pointer.
Herb Sutter has some interesting thoughts on interfaces which are at direct odds with the way most of us implement an interface: http://www.gotw.ca/publications/mill18.htm
Read this awesome piece of internet wisdom: http://www.parashift.com/c++-faq-lite/dtors.html
1) You never need a .cpp file, you can code all your programs in .h, but doing this is terrible style and will inevitabely slow your compilation.
MyClass : public MyInterface {
public:
virtual void myFunction() {
// override and implemenht
}
};
2) When inheriting classes you don't need to worry about declaring your destructor to be virtual, but you need to make sure that classes you are inheriting from have virtual destructors. Otherwise you might be faced with memory leaks. In so far as I know this is not necessary for interface classes with only pure virtual functions.
Destructor being inline makes no difference to you.
Destructor being declared as void is something that should give you a compiler error :).
Edit:
About the 3 types of interfaces, I am getting the sense that you are a little bit confused and this is hampering your googling.
An interface is usually a class that has no functions defined and you must inherit and implement all of them.
A class that has some functionality but still has some pure virtuals is usually called abstract.
When 'zero' functions must be overridden this is neither an interface nor an abstract class, it is just a plain old class that you can inherit and do whatever.
Check out the C++ faq.
Interface where all functions must be overridden by a concrete subclass is called interface
Interface where some functions must be overridden by a concrete subclass is called abstract class
Interface where zero functions must be overridden by a concrete subclass is called class.
You can implement virtual member functions inside header file. They will not inline though, because they have to have address to be placed into virtual table.
... my head is spinning!
To get it spinning more you can also have pure virtual destructor. This is useful trick when you want to have abstract class, but no real useful method to put pure virtual:
class A
{
public:
virtual ~A() = 0;
};
A::~A() {}
class B : public A
{
public:
~B() {}
};
Class A has destructor implemented, but it still can not be instantiated directly, because it is interface. Yet, when it comes to destroying B compiler has to obey to protocol and call ~A(). That is why you have to implement it
I have an existing class that declares a virtual method and defines a default implementation. Now I want to overload that method with a differend parameter and also give a default implementation. Additionaly I want to enforce the constraint, that if the first method got overridden by a subclass then the second (overloaded) virtual method must be overridden too.
Is this even possible inside C++? If so, is it possible at compile time?
Example code:
class ParamA {};
class ParamB {};
class Base
{
public:
virtual void method(ParamA a)
{
// default behavior
}
virtual void method(ParamB b)
{
// default behavior
}
}
class Derived : public Base
{
public:
virutal void method(ParamA)
{
// special behavior
}
}
My goal is to detect classes of type Derived and enforce them to implement their verison of method(ParamB b).
No, you can't specify complex constraints on which sets of member functions must be overridden. The only constraints apply to individual functions; pure virtual (=0) to mandate overriding, and (in C++11) final to prevent overriding.
The best you can do is make both functions pure virtual, forcing the derived class to override both. This at least forces the author of the derived class to think about what needs overriding; it's impossible to override one and forget the other one.
You can still provide a default implementation, so that derived classes that don't want to override either function only need very short overrides that call the default versions.
I think C++ does not provide any means to detect such missing override in a child.
#larsmans: Making both methods pure virtuals leads to missing the default implementation.
#js_: could you elaborate a bit on your actual issue? What you are searching for seems to be conceptually not that clear to me.
How about creating a Parent class from which Base will inherit? These 2 functions will be pure virtual in the Parent class. The derived classes will inherit Parent (and not Base), and will have to implement both functions.
If you all you have to work with is the parent class, then no. It's not possible neither at compile time, nor as a runtime check.
Of course, you could introduce some macros (like say OVERRIDE_METHODS... I'm sure you see what I'm talking about), but nothing can prevent the users from ignoring them and override only one of said methods.
Plus such macros will make the code pretty ugly.