As of How to disable implicitly-defined copy constructor generation when there is user defined destructor it looks like I have to accept the "deprecated" warning, but I am not sure.
You don't have to accept the "deprecated" warning. You have 3 options here, implement the operator, explicit default the operator or delete the operator.
First of all, this warning is trigger because you actually use the copy assignment operator
somewhere. Maybe not even on purpose (see //unfortunate mistake
in the example below). You should actually get a note in addition to the warning where you use the operator, something like:
note: in implicit copy assignment operator for 'CDbMappingComponentAware' first required here
Consider the following example (running version):
class foo {
public:
virtual ~foo() {}
// options
// implement
//foo& operator=(foo const&) {return *this;}
// default
//foo& operator=(foo const&) = default;
// delete
//foo& operator=(foo const&) = delete;
};
class bar : public foo {
public:
~bar() override {};
};
// stupid mistake... should be defined
// void fn(bar const&)
void fn(bar) {}
int main(int, char*[]) {
foo* f1 = new bar;
foo* f2 = new bar;
// triggers warning
*f1 = *f2;
// unfortunate mistake
bar b;
// triggers warning twice since bar inherits from foo
fn(b);
return 0;
}
In the case, you are really using the copy assignment operator
, you should either implement it, or default it if it is really plain vanilla. See below why you eventually should not default it. If you don't want to be able to copy the instance at all, delete the operator/ctor.
By the way, it is the same for copy constructor, not only assignment operator. It is described in §15.8.1/6 for copy constructor and §15.8.2/2 for copy assignment operator in the draft n4727.
However:
But would that not mean I cannot copy a object if I define a virtual dtor (unless I explicitly write a copy assignment operator).
No, you can still use the generated copy ctor/assignment as long as it is a warning. Depreacated means it will (probably) become an error in the future (in case of C++ maybe in about 40 years or more, if at all). So if you don't want your code to spit this warning as an error, when it is not supported by the compiler anymore, you should fix it now.
But why is that? I mean, why is the dtor affecting the copy operator?
Hypothetical answer here:
One purpose I can think of, is to prevent some mistakes. Consider the example (taken from Why doesn’t my constructor work right? ):
class Handle {
private:
string name;
X* p;
public:
Handle(string n)
:name(n), p(0) { /* acquire X called "name" and let p point to it */ }
~Handle() { delete p; /* release X called "name" */ }
};
void f(const string& hh)
{
Handle h1(hh);
Handle h2 = h1; // leads to disaster!
}
Here, the default copy gives us h2.name==h1.name and h2.p==h1.p. This leads to disaster: when we exit f() the destructors for h1 and h2 are invoked and the object pointed to by h1.p and h2.p is deleted twice.
To prevent the double deletion, you have to be explicit and not rely on the generated/ defaulted copy constructor/assignment.
Are you saying the warning is there to enforce the rule of three?
In this particular case: Yes, I would say so.
As I do not deal with resources the rule of three does not make really sense here.
This would require the compiler to take the members in account. Pretty much effort for such an unmature warning.
Personal thoughts:
IMHO, I do not belive this will ever become an error in C++. There is way to much code out there, relying on the auto-generated ctor/assignment. Making this an error would break (literally) tousands of projects. -> Not going to happen...