作为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!!!