c++ - C++11 中的 move 语义

标签 c++ c++11 operators move-semantics move-constructor

我想完全理解 C++11 中的 move 语义。所以我写了几个类来查看何时调用不同的构造函数:

#include <iostream>
using namespace std;

class A {
public:
    A() : a1_(0) {std::cout << "Calling constructor" << std::endl;}
    A(A&& other) {
        std::cout << "Calling move constructor" << std::endl;
        a1_ = other.a1_;
        other.a1_ = 0;
    }

    // Move assignment operator.
    A& operator=(A&& other) {
        std::cout << "Calling move operator" << std::endl;
        if (this != &other) {
            a1_ = other.a1_;
            other.a1_ = 0;
        }
        return *this;
    }

    // Copy constructor.
    A(const A& other) {
        std::cout << "Calling copy constructor" << std::endl;
        a1_ = other.a1_;
    }

    // Copy assignment operator.
    A& operator=(const A& other) {
        std::cout << "Calling copy assignment operator" << std::endl;
        if (this != &other) {
            a1_ = other.a1_;
        }
        return *this;
    }

private:
    int a1_;
};

class B {
    A oA_;

public:
    B() {}
    void setoA(A a) {oA_ = a;}
        A getoA() {return oA_;}
};

A createA() {
    A a1;
    return a1;
}

B createB() {
    B tmpB;
    A tmpA;
    tmpB.setoA(tmpA);
    return tmpB;
}

int main() {
    B b;
    A a;
    b.setoA(a);
    std::cout << "**************************" << std::endl;
    b.setoA(createA());
    std::cout << "**************************" << std::endl;
    b.setoA(std::move(createA()));
    std::cout << "**************************" << std::endl;
    B b2;
    b2.setoA(b.getoA());
    std::cout << "**************************" << std::endl;
    createB();

    return 0;
}

当我检查这段代码的输出时:

    Calling constructor

    Calling constructor

    Calling copy constructor

    Calling copy assignment operator

    ++++++++++++++++++++++++++++++++++

    Calling constructor

    Calling copy assignment operator

    ++++++++++++++++++++++++++++++++++

    Calling constructor

    Calling move constructor

    Calling copy assignment operator

    ++++++++++++++++++++++++++++++++++

    Calling constructor

    Calling copy constructor

    Calling copy assignment operator

    ++++++++++++++++++++++++++++++++++

    Calling constructor

    Calling constructor

    Calling copy constructor

    Calling copy assignment operator

这里有一些疑惑:

我以为如果你传递r-value, move 构造函数就会被调用,是吗?这不是 b.setoA(createA()); 一个 r-value 吗?

如何调用 move 构造函数/运算符?

最佳答案

First of all in first section, why is constructor being called twice?

因为您构造了 BA,前者有自己的 A 实例,第一个(意想不到的)构造函数调用来自。

I thought that if you pass r-value move constructor will be called, is that right? Isn't this b.setoA(createA()); an r-value?

构造函数是从 createA 中调用的(是的,返回值 一个右值),然而,复制省略发生并且对象直接在setoA 的参数变量。

然而,在 setoA 中,复制赋值被选中,因为现在 a 是一个左值。如果你想搬家,你需要:

void setoA(A a) { oA_ = std::move(a); }

关于c++ - C++11 中的 move 语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51522536/

相关文章:

c++ - 什么样的C++模板编程可以调用 "meta programming"?

c++ - 在 Qt 中确定 TCP 套接字上的数据类型

c++ - std::is_class 的实现

c++ - 如何在 C++ 中编写 ofstream vector ,它接收所有不同的输出流,如 cout、字符串流和 ofstream

c++ - 如何重载运算符 <<

c++ - 将双字节字符转换为整数 C++

c++ - C++标准的问题

C++11 - 构造函数继承

c++ - 将所有模板类型传递给运算符而不指定所有类型

c++ - 如何重载箭头取消引用运算符->() 不是针对实体对象而是针对指针