Let's say I have this class:
class Test
{
public:
Test();
};
AFAIK, compiler provides default copy constructor and assignment operators, which assign every member of other instance to the current instance. Now I add move constructor and assignment:
class Test
{
public:
Test();
Test(Test&& other);
Test& operator=(Test&& other);
};
Does this class still contain compiler-generated copy constructor and assignment operators, or 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;
}
Prints 2 12345 2 12345
. Compiler: VC++ 2010. According to this test, copy constructor and assignment are still here. Is this standard behavior, can I be sure that this will work on every C++ compiler?
From 12.8-7 Copying and moving class objects [class.copy]
If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (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 operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor...
According to this, since you have declared a move constructor and a move assignment operator, but no copy assignment operator, copy constructor or destructor, you do not get the implicitly generated copy constructor or assignment operator. The compiler gives you their 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 produced by g++ 4.8.1
ctors.cpp:13:13: error: use of deleted function 'constexpr Test::Test(const Test&)'
Test t2(t1);
ctors.cpp:1:8: note: 'constexpr Test::Test(const Test&)' is implicitly declared as deleted because 'Test' declares a move constructor or move assignment operator
struct Test
(emphasis mine)
According to section 12.8 Copying and moving class objects of the C++ Standard
7 If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4).
18 If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted (8.4).
So in your case and the copy constructor and the copy assignment operator are implicitly declared by the compiler but defined as deleted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With