C ++ states that move / copy operation will suppress generation of linked operations?

I saw a sentence in the C ++ programming language that I got confused with:

β€’ If the programmer declares a copy, move, or destructor for a class, no copy, move, or destructor is created for that class.

I wrote the test code shown below:

#include <iostream>
using namespace std;
class A
{
public:
    A() :a(0){}
    A(int _a) :a(_a){}
    int get() const
    {
        return a;
    }
    /*A& operator=(const A &x)
    {
        a = x.a;
        cout << "A copy assignment" << endl;
        return *this;
    }*/
    A& operator=(A&&x)
    {
        cout << "A move assignment" << endl;
        swap(a, x.a); 
        return *this;
    }
private:
    int a;
};

A operator+(const A &x, const A &y)
{
    A temp{ x.get() + y.get() };
    return temp;
}

int main() 
{
    A a1(1), a2(2), a3;
    a3 = a1;
    cout << a3.get() << endl;
    return 0;
}

      

Result: enter image description here

I define the transfer destination, there should be no default copy destination generated as the book says, but how can a3 get a copy of a1?

Another question:

I changed the a3 assignment expression:

a3 = a1+a2;

      

result: enter image description here

Then I'll comment out the move assignment and remove the comment on the copy assignment:

A& operator=(const A &x)
{
    a = x.a;
    cout << "A copy assignment" << endl;
    return *this;
}
/*
A& operator=(A&&x)
{
    cout << "A move assignment" << endl;
    swap(a, x.a); 
    return *this;
}*/

      

result: enter image description here

how could copy be scheduled? The result of a1 + a2 is an rvalue, how can this rvalue be passed for a copy assignment whose argument is const A & ? Pardon my confusion about rvalues

any help is appreciated!

+3


source to share


2 answers


I define the transfer destination, there should be no default copy destination generated as the book says

Right.

but how can a3 get a copy of a1?

He couldn't live up to the standard. If the compiler doesn't give you a diagnostic message for this, then the compiler is not standard compliant.




The result a1+a2

is an rvalue

Right.

how can this value be passed to the copy destination which argument is const A&

?

Since rvalues ​​can be bound to lvalue references to const

. The lifetime of the temporary object is extended to match the potential lifetime of the link. That is, for the entire duration of the function in the case of a pivot argument.

+3


source


Based on some practical experimentation with GCC 6 and this (somewhat confusing) suggestion, I found the following:



  • If you declare any other constructor for a class, there is no default constructor defined.
  • If you declare a copy operation (constructor or assignment operator), another copy operation is generated implicitly. However, this generation is not recommended by the ISO standard, as described in the paragraph after the sentence in the book.
  • If you declare a destructor, copy operations are generated implicitly. This is also not recommended.
  • If you declare a copy operation, move operations are implicitly removed (by default, operations are copied, as shown below).
  • If you declare a move operation, the other move operation is implicitly removed.
  • If you declare a move operation, copy operations are implicitly removed.
  • If you declare a destructor, any code that uses implicit move operations uses implicit copy operations (or explicit ones if defined) instead. However, this may be implicitly deprecated from what has been learned above.
  • If no explicit destructor has been defined, it seems that a default (empty) destructor is always created for the class, no matter what other operations were or were not defined.
0


source







All Articles