c++ - move 构造函数

标签 c++ c++11 move

我试图理解 move 构造函数并编写了以下代码

#include<iostream>
#include<string>
using namespace std;

class mystring
{
    string s;
public:
    mystring(const string& x):
    s(x)
    {

    }
    mystring(const mystring& x)

    {
        cout<<"Copy called"<<endl;
        s = x.s;
    }


    mystring(const mystring&& x)
    {
        cout<<"Move Called"<<endl;
        s = x.s;
    }

    mystring& operator+(const mystring& x)
    {
        cout<<"+ operator"<<endl;
        s = s+x.s;
        return *this;
    }
};

int main()
{
    string a = "Hello ";
    string b = "World ";
    mystring a1(a);
    mystring b1(b);
    mystring c = mystring(a1+b1);
}

我期望在 a1+b1 的结果 rValue 上调用 move 构造函数,但我看到只调用了复制构造函数。我错过了什么吗?

gcc --version
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0

在 HolyBlackCat 的回答后编辑:

#include<iostream>
#include<string>
using namespace std;

class mystring
{
    string s;
public:
    explicit mystring(const string& x):
    s(x)
    {
        cout<<"ctor called"<<endl;
    }
    mystring(const mystring& x)

    {
        cout<<"Copy called"<<endl;
        s = x.s;
    }


    mystring(mystring&& x)
    {
        cout<<"Move Called"<<endl;
        s = std::move(x.s);
    }

    mystring operator+(const mystring& x) const
    {
        cout<<"+ operator"<<endl;
        return mystring(s+x.s);
    }
};

int main()
{
    string a = "Hello ";
    string b = "World ";
    mystring a1(a);
    mystring b1(b);
    mystring c(a1+b1) ;
} 

move 构造函数仍然没有被调用:

ctor called
ctor called
+ operator
ctor called

最佳答案

没有理由调用 move 构造函数,因为您的 operator+ 不返回临时值。


修改operator+中的左操作数是个坏主意。没有人期望 a + b 修改 a

您应该将其重写为mystring operator+(const mystring& x) const。这样它确实返回一个临时的,并且应该调用你的 move 构造函数(除非编译器 optimizes it away )。

此外, move 构造函数/赋值的参数通常应该是const 右值引用。您需要能够修改参数以从中 move 资源。

另外,请注意右值引用是左值。这听起来可能很奇怪,但重点是如果没有 std::move,即使 xs = x.s 也会复制字符串>std::string &&.

最后, move 构造函数应该是这样的:

mystring(mystring &&x)
{
    cout << "Move Called" << endl;
    s = std::move(x.s);
}

或者更好,像这样:

mystring(mystring &&x) : s(std::move(x.s))
{
    cout << "Move Called" << endl;
}

关于c++ - move 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57344029/

相关文章:

c++ - FreeType 中的 Unicode 问题

jquery - 多个 Div 均以可变速度跟随光标

php - 如何使用 php 将文件 move 到另一个文件夹?

c++ - 比率乘法期间的 chrono::duration_cast 问题

c++ - 在不增加引用计数的情况下迭代共享指针映射?

c++ - 为什么析构函数会禁用隐式 move 方法的生成?

c++ - 使用相同的初始化列表构造数组的所有元素的 DRY 方法?

c++ - 无法链接到 OSX High Sierra 中的 libclang

c++ - 对于 Cmake,您可以使用 `add_compiler_flags()` 命令修改发布/调试编译器标志吗?

c++ - C99 和 C++ 的内联函数的兼容定义