Default instance constructor and assignment for a class with a move constructor and assignment

Say I have this class:

class Test { public: Test(); }; 

AFAIK, the compiler provides standard default constructors and assignment operators that assign each member of another instance to the current instance. Now I add a move constructor and assignment:

 class Test { public: Test(); Test(Test&& other); Test& operator=(Test&& other); }; 

Does this class still contain a constructor compiler and an assignment operator, or do I need to implement them?

Edit This is my test:

 class Test { public: Test(){} Test(Test&& other){} Test& operator=(Test&& other) { return *this; } int n; char str[STR_SIZE]; }; int main() { Test t1; t1.n = 2; strcpy(t1.str, "12345"); Test t2(t1); Test t3; t3 = t1; cout << t2.n << " " << t2.str << " " << t3.n << " " << t3.str << endl; return 0; } 

Print 2 12345 2 12345 . Compiler: VC ++ 2010. According to this test, the constructor and purpose of the copy is still here. Is this standard behavior, can I be sure that this will work on every C ++ compiler?

+5
source share
2 answers

From 12.8-7 Copying and Moving Class Objects [class.copy]

If the class definition does not explicitly declare the copy constructor, it is declared implicitly. If the class definition declares a move constructor or moves an assignment operator, the 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 ...

From 12.8-18

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

Accordingly, since you declared a move constructor and a move assignment operator, but do not use a copy assignment operator, copy constructor, or destructor, you do not receive an implicitly generated copy constructor or assignment operator, the Compiler provides you with its declarations, but they are declared as deleted .

Here is a simplified version of your example:

 struct Test { public: Test(){} Test(Test&& other){} Test& operator=(Test&& other) { return *this;} }; int main() { Test t1; Test t2(t1); } 

And the error created by g ++ 4.8.1

ctors.cpp: 13: 13: error: using the remote function 'constexpr Test :: Test (const Test &)'

Testing t2 (t1);

ctors.cpp: 1: 8: note: 'constexpr Test :: Test (const Test &)' is implicitly declared remote because 'Test' declares a move constructor or transfers an assignment operator

struct test

(my emphasis)

+6
source

According to Section 12.8 Copying and Moving Objects of the C ++ Standard Class

7 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).

18 If the class definition does not explicitly declare a copy of the assignment operator, one is declared implicitly. If the definition class declares a move constructor or move destination operator, the implicitly declared copy destination operator is determined to be excluded; otherwise, it is defined as default (8.4).

So, in your case, both the copy constructor and copy assignment operator are implicitly declared by the compiler, but are defined as deleted.

+1
source

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


All Articles