#3 should really say make public base class destructors virtual
#6 sometimes you actually will want an A(A&) constructor... for example, if you have constructor overloaded with a greedy template argument.
#8 objects returned by value will also bind to an rvalue reference
#9 Remember in C++11 there's also new T{};
#10 isn't absolutely correct either, dynamic_cast can actually be used in some circumstances where static_cast or implicit casting could have been used.
struct A {
};
struct B: A {
};
int main() {
auto b = new B();
auto a = dynamic_cast<A*>(b); // fine
}
I haven't touched C++ in years. Why would you ever make a non-virtual destructor? Isn't it totally up to the user of a class if they choose to inherit from the class?
It seems like, if you're not providing a virtual destructor, you force users into delegation rather than inheritance, and that will catch some % of developers who aren't on the ball. They'll have leaks...
As far as i know (old info) there's no such thing as a "final" class, so anybody can inherit even if you don't want them to.
Having any virtual member functions, unless the compiler can devirtualize it, will hurt both space usage (since you now need a per-object vtable) and cache performance (since destruction now has to go through an indirection every time, instead of being a globally visible function).
You have the `final` specifier since C++11 to state a class cannot be inherited from, but this notion of "You really shouldn't inherit from this class." has been around since classical object orientation has, C++ just couldn't express it as a language.
So if your class currently isn't being inherited from, make your public dtor nonvirtual. If and when it needs to be a base class, then the author can modify your class to have a virtual dtor, or use composition (which is often the superior alternative). If source code is not available, then composition it is. I would advise against making it virtual "just in case", that's premature pessimisation.
Right, but unless your Base or Derived class is going to pass Base*/&s to friends and/or other instances, you typically don't want your protected destructors to be virtual just so you can get safe destruction. Of course, the thing with C++ is, the longer you sit and think about it, the more reasons you can come up with a reason to do something atypical
Slicing isn't even necessarily harmful either... but I'm not sure what you had in mind.
struct A {
A (A const&); // copy constructor;
A (A&&); // move constructor
template <typename T> A (T&&); // template constructor
};
int main() {
A a1;
A a2(a1); // calls the template constructor because a1 is an lvalue
}
#6 sometimes you actually will want an A(A&) constructor... for example, if you have constructor overloaded with a greedy template argument.
#8 objects returned by value will also bind to an rvalue reference
#9 Remember in C++11 there's also new T{};
#10 isn't absolutely correct either, dynamic_cast can actually be used in some circumstances where static_cast or implicit casting could have been used.