为什么在将对象设置为等于另一个函数的返回值时调用了移动构造函数/赋值

时间:2018-02-22 10:05:43

标签: c++

=IFNA(VLOOKUP(C$6,Bullet!AB:AC,1+F5,FALSE),0)

在输出中:

#include <iostream>

class Box{
public:
int x;
Box(){
    x=0;
    std::cout << "Constructor" << std::endl;
}
Box(const Box& other){
    x = other.x;
    std::cout << "Copy constructor" << std::endl;
}
Box(Box&& other){
    x = other.x;
    other.x = 0;
    std::cout << "Move constructor" << std::endl;
}

Box& operator=(Box&& other) {
    x = other.x;
    other.x = 0;
    std::cout << "Move assignment" << std::endl;
    return *this;
}

Box& operator=(const Box &other){
    x = other.x;
    std::cout << "Copy assignment" << std::endl;
}

~Box(){
    std::cout << "Destructor" << std::endl;
    x=0;
}
};
Box send(Box b){
std::cout << "Sending" << std::endl;
return b;
}
int main(){
Box b1, b2;
b1 = send(b2);
return 0;
}   

我不太确定为什么在执行Constructor Constructor Copy Constructor Sending Move Constructor Move Assignment Destructor Destructor Destructor Destructor 时使用了移动构造函数然后赋值。

2 个答案:

答案 0 :(得分:1)

它是从参数b移动构造返回值,然后将该返回值移动分配给b1

答案 1 :(得分:1)

  

为什么在设置对象等于另一个函数的返回值时调用了移动构造函数/赋值

您的send函数返回b这是一个参数,而不是局部变量:

Box send(Box b) {
    std::cout << "Sending" << std::endl;
    return b; // b is a parameter
}

因此没有发生RVO优化,因为returning a parameter disables RVO。 同时,还有另一种优化选项,隐式std::move

Box send(Box b) {
    std::cout << "Sending" << std::endl;
    return std::move(b); // implicit std::move is applied.
}

所以它是使用你的移动构造函数构建的:

Box(Box&& other);

如果您创建并返回本地变量c,您将看不到移动构造:

Box send(Box b) {
    Box c;
    std::cout << "Sending" << std::endl;
    return c; // Returns c, not b -> No move construction thanks to RVO
}

因为RVO然后跳进来。