C++ 拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值运算符示例分析

作为C++新人,常常不明白上述四种C++函数/运算符的意义及分别在什么情况下会执行对应的函数/运算符。

拷贝构造函数(Copy constructor):由已有的类拷贝创建一个新类,调用该构造函数。

        函数参数为:class-name&  (左值引用),其中 class-name 是为其定义构造函数的类的名称。

class Window
{
    public:
    Window(const Window& a){
    }
    // ...
};


拷贝赋值运算符(Copy assignment operator):将已创建的类赋值给一个新类,调用该构造函数。

        该运算符的参数为:class-name&  (左值引用),其中 class-name 是为其定义构造函数的类的名称。注意这里的参数是引用,我想了下,如果不是引用的话,应该会引发无限循环问题。

class Window{
    public:    
    void operator=(const Window& a) {
    }
    //...
}


移动构造函数(Move constructor):用std::move(右值引用)的方式创建一个新类,调用该构造函数。

        该函数的参数为:class-name&&  (右值引用) ,其中 class-name 是为其定义构造函数的类的名称。

class Window
{
    public:
    Window(const Window&& a) {
    }
    // ...
};


移动赋值运算符(Move assignment operator):用std::move(右值引用)的方式将已创建的类赋值给一个新类,调用该构造函数。

        该运算符的参数为:class-name&&  (右值引用) ,其中 class-name 是为其定义构造函数的类的名称。

class Window
{
    public:
    void operator=(const Window&& a) {
    }
    // ...
};


上述函数及运算符尽可能创建该类型的参数为 const类型,这可防止复制构造函数意外更改从中复制它的对象。 

示例代码:

#include <iostream>
#include <memory>
#include <vector>
#include <string>
using namespace std;
 
class RValue {
    public:
    //简单初始化的构造函数
    RValue():sources("hello!!!"){
            cout<<"constructor---> " << "init string"<<endl;    
    }
 
    //拷贝构造函数
    RValue(const RValue& a) {
        sources = a.sources;
        cout<< "Copy constructor---> "<< "& RValue"<<endl;
    }
        
    //拷贝赋值运算符
    void operator=(const RValue& a) {
        sources = a.sources;
        cout<< "Copy assignment operator---> " <<"& =="<<endl;
    }
        
    //移动构造函数    
    RValue(RValue&& a) {
        sources = std::move(a.sources);
        cout<< "Move constructor---> " <<"&& RValue"<<endl;
    }
 
    //移动赋值运算符
    void operator=(const RValue&& a) {
        sources = std::move(a.sources);
        cout<< "Move assignment operator---> " << "&& =="<<endl;
    }
 
    string sources;;
};
 
RValue get() {
        RValue a;
    return a;
}
 
void put(RValue){}
 
int main() {
    //constructor
    RValue a, b;    
    cout<<"a.sources:"<<a.sources<<endl;
    cout<<"b.sources:"<<a.sources<<endl;
    
    //Copy constructor
    RValue b1(b);            // method 1
    cout<<"b.sources:"<<b.sources<<endl;
    cout<<"b1.sources:"<<b1.sources<<endl;
    RValue c = b1;        // method 2
    cout<<"c.sources:"<<c.sources<<endl;
    cout<<"b1.sources:"<<b1.sources<<endl;    
    
    //Copy assignment operator
    RValue d;    
    d = c;
    cout<<"d.sources:"<<d.sources<<endl;    
        
    //Move constructor        
    RValue a1 = std::move(a);     // method 1
    cout<<"a.sources:"<<a.sources<<endl;
    cout<<"a1.sources:"<<a1.sources<<endl;     
    RValue a2(std::move(b))    ;        // method 2
    cout<<"a.sources:"<<b.sources<<endl;
    cout<<"a2.sources:"<<a2.sources<<endl;
 
    //Move assignment operator
    RValue e;    
    e = std::move(d);
    cout<<"d.sources:"<<d.sources<<endl;    
    cout<<"e.sources:"<<e.sources<<endl;    
    return 0;
}


执行结果如下:

constructor---> init string
constructor---> init string
a.sources:hello!!!
b.sources:hello!!!
Copy constructor---> & RValue
b.sources:hello!!!
b1.sources:hello!!!
Copy constructor---> & RValue
c.sources:hello!!!
b1.sources:hello!!!
constructor---> init string
Copy assignment operator---> & ==
d.sources:hello!!!
Move constructor---> && RValue
a.sources:
a1.sources:hello!!!
Move constructor---> && RValue
a.sources:
a2.sources:hello!!!
constructor---> init string
Move assignment operator---> && ==
d.sources:hello!!!
e.sources:hello!!!
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值