Add implicit virtual destructors to class using the virtual keyword

1,437 views
Skip to first unread message

Nathan Oliver

unread,
Mar 21, 2019, 5:29:54 PM3/21/19
to ISO C++ Standard - Future Proposals
Today I encountered the following code on Stack Overflow which will not compile as it tries to copy the return value.

struct B {};

struct A{
    std
::unique_ptr<B> x;
   
virtual ~A() = default;
};

A f
() {
    A tmp
;
   
return tmp;
}

The problem here is that since the user declared the destructor so it could be virtual, it removed the implicitly generated move operations.  This can be solved by explicitly defaulting the operations, which adds code you have to type which introduces more places to create a bug, or you can inherit from a class that only has a virtual destructor.  This is less prone to bugs but it is still writing boiler plate to add just to get a default virtual destructor.  I think it would be nice to have the ability to mark A in such a way that the compiler can make its implicitly generated destructor default.  Something along the lines of

virtual struct A {
    std
::unique_ptr<B> x;
};

Would be nice to be able to do to tell the compiler to generate a virtual destructor and allows you to follow the rule of zero.

Tony V E

unread,
Mar 21, 2019, 5:51:11 PM3/21/19
to Standard Proposals
If your class has a virtual destructor it is probably polymorphic (alternatively, if it is not polymorphic, don't give it a virtual destructor).
If your class is polymorphic, you probably don't want it to have a copy constructor, as the copy probably isn't going to copy the polymorphic (ie most-derived) parts.

Now, some people believe (and teach) that all classes should have virtual destructors, in case someone wants to later derive from them.
Those people are wrong. Classes should be designed for polymorphism (or not); it is not a post-class decision.

You should (typically) only have a virtual destructor if you have other virtual functions, which you have because you want polymorphism.
(What the standard _should_ do (but would break code and/or ABI somewhere) is to give you a virtual destructor automatically when you have virtual functions.)

So, I don't understand why you want virtual destructor AND rule of zero together.
Tony


--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9a1898a8-77dc-42a3-8b62-67f49dcaaac6%40isocpp.org.


--
Be seeing you,
Tony

Balog Pal

unread,
Mar 26, 2019, 6:52:46 AM3/26/19
to ISO C++ Standard - Future Proposals


2019. március 21., csütörtök 22:29:54 UTC+1 időpontban Nathan Oliver a következőt írta:
The problem here is that since the user declared the destructor so it could be virtual, it removed the implicitly generated move operations.  This can be solved by explicitly defaulting the operations, which adds code you have to type which introduces more places to create a bug, or you can inherit from a class that only has a virtual destructor.  This is less prone to bugs but it is still writing boiler plate to add just to get a default virtual destructor.  I think it would be nice to have the ability to mark A in such a way that the compiler can make its implicitly generated destructor default. 

Yeah, it is pretty bad that the rules have 'user-declared' in many places and if you use =default it is still counts as user-declared with all the unwanted consequences.   But it will unlikely change in general. And standard's rules about generating virtual dtor seeing virtual functions or or the change you seek will not change due to silently changing the meaning of too much code out there.  Especially for the sake of RARE cases, that are easy to solve too.

Instead of declaring the virtual dtor directly, create an empty base class VirtualDtor with just the virtual dtor and the 4 other auto functions =default. And inherit from that, it giver you all the desired functionality.



Reply all
Reply to author
Forward
0 new messages