What using copy-constructor if a class contains a user-declared destructor?

The standard in section 12.8 / 7 states:

If the class definition does not explicitly declare a copy of the constructor, one is declared implicitly. If a class definition declares a move constructor or a move carry operator, an implicitly declared copy constructor is defined as deleted; otherwise, it is defined as default (8.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor. So for class definition

struct X { X(const X&, int); }; 

The copy constructor is implicitly declared. If a user-declared constructor is later defined as

 X::X(const X& x, int i =0) { /∗ ... ∗/ } 

I cannot understand that the latter case is out of date if the class has a user-declared copy destination operator or a user-declared destructor. In this example, the standard does not provide a custom copy assignment operator and destructor. What happens if we declare a destructor or copy assignment operator? I tried to do it as follows:

 struct A { ~A(){ }; }; A::A(const A&){ }; //error int main(){ } 

Demo

but in this example, we still have an implicitly declared copy constructor. What does this rule mean?

I thought that if we write the following:

 struct A { A(){ }; A(const A&&){ }; ~A(){ }; }; A a; A t = a; //error: call to implicitly-deleted copy constructor of 'A' int main() { } 

Demo

the copy constructor will not be explicitly deleted. But it's not that.

+6
source share
2 answers

This obsolescence mainly uses rule three (five). If a custom copy destination agent or destructor is provided, then the fact that the copy constructor is defined as default (and not remote) is deprecated. This should prevent you from depending on such an implicitly declared copy constructor in the future.

In this example, the standard does not provide for copying, nor is the destructor generated by the user.

The example has nothing to do with the deprecated one.

I tried to do it this way: [...] but in this example we still have an instance with an impliclty constructor declaration.

You cannot define an implicitly declared copy constructor because it is already defined, = default (no pun intended). You will have to declare it first.

I thought that if we create the following: [...] the copy constructor will not be explicitly deleted. But this is not so.

You specified a rule that explicitly states that the copy constructor will be implicitly defined as remote if the move constructor is declared:

If a class definition declares a move constructor or move assignment operator, an implicitly declared copy constructor is defined as remote;

It's obvious that

 A(const A&&){ } 

Is a move constructor according to [class.copy] / 3. If you delete this move constructor, then your example compiles , although it uses the specified obsolete function.

+4
source

Fatigue usually means that something will work, but that it is not approved and may not work in the future. I think the standard says that if you create a user-declared copy destination operator or a user-declared destructor, it will still create a default copy constructor (if you did not), but it may not be in the future. Therefore, they want you to now create your own copy constructor if you have one of the other two, and in the future they can force you.

0
source

Source: https://habr.com/ru/post/977579/


All Articles