You do not need to explicitly declare the destructor in a derived class:
§ 15.4 Destructors [class.dtor] (emphasis mine)
A destructor can be declared virtual (13.3) or pure virtual (13.4); if
any objects of that class or any derived class are created in the
program, the destructor shall be defined. If a class has a base class
with a virtual destructor, its destructor (whether user- or
implicitly-declared) is virtual.
In fact, it might even be detrimental to performance in some cases, as explicitly declaring a destructor will prevent the implicit generation of a move constructor and move assignment operator.
Unless you need to do something in your destructor, the best course of action would be to just omit an explicit declaration of a destructor.
If you do need a custom destructor, and are certain that the default copy ctor, copy assignment operator, move ctor and move assignment operator would do the correct thing for you, it is best to explicitly default them like so:
MyError(const MyError&) = default;
MyError(MyError&&) = default;
MyError& operator=(const MyError&) = default;
MyError& operator=(MyError&&) = default;
Some reasoning on why you're seeing the error, because this used to be perfeclty valid code in C++98:
As of C++11, implicit generation of the copy constructor is declared as deprecated.
§ D.2 Implicit declaration of copy functions [depr.impldec]
The implicit definition of a copy constructor as defaulted is
deprecated if the class has a user-declared copy assignment operator
or a user-declared destructor. The implicit definition of a copy
assignment operator as defaulted is deprecated if the class has a
user-declared copy constructor or a user-declared destructor (15.4,
15.8). In a future revision of this International Standard, these implicit definitions could become deleted (11.4).
The rationale behind this text is the well-known Rule of three.
All quotes below are sourced from cppreference.com: https://en.cppreference.com/w/cpp/language/rule_of_three
Rule of Three
If a class requires a user-defined destructor, a user-defined copy
constructor, or a user-defined copy assignment operator, it almost
certainly requires all three.
The reason why this rule of thumb exists is because the default generated dtor, copy ctor and assignment operator for handling different types of resources (most notably pointers to memory, but also others, like file descriptors and network sockets to name just a couple) rarely do the correct behaviour. If the programmer thought that he needed special handling for the closing of a file handle in the class destructor, he most surely wants to define how this class should be copied or moved.
For completeness, below are the often related Rule of 5, and the somewhat disputed Rule of Zero
Rule of Five
Because the presence of a user-defined destructor, copy-constructor,
or copy-assignment operator prevents implicit definition of the move
constructor and the move assignment operator, any class for which move
semantics are desirable, has to declare all five special member
functions:
Rule of Zero
Classes that have custom destructors, copy/move constructors or
copy/move assignment operators should deal exclusively with ownership
(which follows from the Single Responsibility Principle). Other
classes should not have custom destructors, copy/move constructors or
copy/move assignment operators.
MyError(MyError const&) = default;
to suppress the warning. You can also get rid of the destructor definition because it will be implicitly virtual due to the base class' destructor being virtual – Citronellal-Wdeprecated
to reproduce it. Looks like problem is a configuration of compiler. Do you use some custom compiler options? – Styria/Wall
command-line switch, the same warning appearswarning C5267: definition of implicit copy constructor for 'MyError' is deprecated because it has a user-provided destructor
– Chlorohydrin