3

Is there any valid and usable case, that will force you not to use the virtual keyword before the destructor.

class Base {
public:
  virtual ~Base() { ... } // `virtual` causes error (not compile time or syntax) or wrong behaviour
  // could contain other fields

};

// some example 
arsdever
  • 1,111
  • 1
  • 11
  • 32
  • 3
    I don't understand. You use `virtual` when you need it. You do not use `virtual` when you do not need it. – L. F. Jun 11 '19 at 12:07
  • What is the problem you have? Perhaps you should ask about that directly instead? – Some programmer dude Jun 11 '19 at 12:08
  • The question, if I understood it correctly, is the opposite one: "When *not* to use virtual destructors?" – Evg Jun 11 '19 at 12:10
  • I mean a case, where you will be forced to remove `virtual` from a destructor. It will not give any compiler/syntax errors but will cause wrong behaviour. – arsdever Jun 11 '19 at 12:11
  • "Wrong behavior" is also something you could ask about here. Create a [mcve] that replicates the "wrong behavior" and post a new question about it. – Some programmer dude Jun 11 '19 at 12:21
  • If the Base class is not intended to be used as a way to destruct derived classes, then a non-virtual protected destructor would be warranted. (Other languages may calls such classes an `interface`, but C++ doesn't distinguish between the two as part of the core language.) – Eljay Jun 11 '19 at 12:38

2 Answers2

6

It's possible that making the destructor virtual could convert your class from a non-polymorphic type to a polymorphic type.

Note that a polymorphic type is never trivially copyable. So, for example, you could break any use of std::memcpy by the introduction of a virtual destructor.

In some situations - particularly when interoperating with C - that can wreak havoc, as you can no longer assume that the address of an instance of your class is the same as the address of the first member.

Reference: https://en.cppreference.com/w/cpp/types/is_trivially_copyable

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • You mean, that the problem comes not from the virtuality of the destructor, but the virtuality itself. Am I right? – arsdever Jun 11 '19 at 12:52
  • 1
    @arsdever: Yes. The destructor is the means by which your type becomes virtual if it wasn't already. – Bathsheba Jun 11 '19 at 12:55
3

Is there any valid and usable case, that will force you not to use the virtual keyword before the destructor.

Yes. If you ever use std::memcpy or std::memcmp with instances of the class or its members, or rely on a pointer to/from an instance being convertible to the first member of the class,or examine common initial sequence of an inactive union member of the class type.

In general: If you rely on the class being a standard-layout type or trivially copyable, then the destructor (as well as all other member functions) must be non-virtual. Most cases of erroneously assuming standard-layoutness or triviality have undefined behaviour. Those properties can be enforced with type traits and static asserts, so that you get a nice compilation error instead.

eerorika
  • 232,697
  • 12
  • 197
  • 326