c++ 默认移动构造函数

先上结论 ^ ^:(如有不对,请指正)

if (定义了 拷贝构造函数 、 拷贝赋值运算符 或 析构函数) {
    不会合成移动构造函数和移动赋值运算符。此时会使用对应 拷贝 操作来代替 移动
}
else if (类的所有成员都可以移动) {
    则会为类合成移动构造函数或移动赋值运算符。
}
else {
    合成拷贝构造函数和拷贝复制运算符。
}


class Test {
public:
    Test(int v, const string& str) {
        p = new int(v);
        s = str;
        cout << "test()" << endl;
    }
    ~Test() {
        cout << "~Test()" << endl;
        delete p;
        p = nullptr;
    }
private:
    int* p = nullptr;
    string s;
};
int main() {
    Test c(10, "1234");
    Test k = std::move(c);
    return 0;
}

反汇编:
在这里插入图片描述
在这里插入图片描述
可见,此时调用Test k = std::move(c);实际调用的是Test(const Test &); 是copy-construct ;
当然,如果Test定义了Test(const Test& t) 则肯定调用copy-construct ,但是如果定义Test(Test& t) 则会报编译错误。



class Test {
public:
    Test(int v, const string& str) {
        p = new int(v);
        s = str;
        cout << "test()" << endl;
    }
     Test(const Test& t) {
         p = new int(*t.p);
         cout << "test&" << endl;
     }
     Test(Test&& t) noexcept {

         p = t.p;
         t.p = nullptr;
         cout << "test&&" << endl;
     }
     ~Test() {
         cout << "~Test()" << endl;
         delete p;
        p = nullptr;
    }
private:
    int* p = nullptr;
    string s;
};
int main() {
    Test c(10, "1234");
    Test k = std::move(c);
    return 0;
}

如果定义了Test(Test&& t) ,则Test k = std::move(c); 肯定调用的是move-construct。


class Test {
public:
    Test(int v, const string& str) {
        p = new int(v);
        s = str;
        cout << "test()" << endl;
    }
private:
    int* p = nullptr;
    string s;
};
int main() {
    Test c(10, "1234");
    Test k = std::move(c);
    return 0;
}

在这里插入图片描述
在这里插入图片描述
这里把析构函数去掉了,此时Test k = std::move(c); 使用了编译器默认生成的move-construct



class NoMove {
public:
    NoMove(NoMove&&) = delete;
private:    
    int i;
};
int main() {
    NoMove g; //C2512	“NoMove”: 没有合适的默认构造函数可用
    return 0;
}

给NoMove类定义NoMove(NoMove&&) = delete;以后,NoMove的copy-construct和default-construct被删除,所以报错。


class NoMove {
public:
    NoMove() = default;
    NoMove(const NoMove&) = default;
    NoMove(NoMove&&) = delete;
private:    
    int i;
};

class Test {
public:
    Test(int v, const string& str)  {
        p = new int(v);
        s = str;
        cout << "test()" << endl;
    }
private:
    int* p = nullptr;
    string s;
    NoMove no;
};

int main() {
    Test c(10, "1234");
    Test k = std::move(c);
    return 0;
}

此时因为NoMove成员没有move-construct,所以Test k = std::move(c); 还是调用了copy-construct.


版权声明:本文为weixin_44240548原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。