赋值运算符
注意几点:
- 参数定义为
MyStr& operator =(const MyStr& str)
,const可以接收左值引用和右值引用(为啥可以参考:C++11之右值引用&移动语义。 - 判断入参是否是本身
- 返回参数为引用。原因除了避免拷贝、避免临时对象出现后在栈中需要多增加的一次拷贝外,另外是可以实现连续赋值,即类似a=b=c这样。如果不是返回引用而是返回值类型,那么,执行a=b时,调用赋值运算符重载函数,在函数返回时,由于返回的是值类型,所以要对return后边的“东西”进行一次拷贝,得到一个未命名的副本(有些资料上称之为“匿名对象”),然后将这个副本返回,而这个副本是右值,所以,执行a=b后,得到的是一个右值,即右值=c,再执行=c就会出错。
调用时机
什么情况下调用赋值运算符,什么情况下调用拷贝构造函数?
简单来说=
号右边是一个前面已经定义好的变量时,是调用的赋值运算符。如下所示c1 = c;
,是c1调用了operator =()
函数。
Array c(5);
Array c1(50);
Array d = c; // 拷贝构造函数
c1 = c; // 赋值运算符
移动赋值运算符
主要是为了接收右值的赋值操作。定义为:Array& operator=(Array &&rhs)
。
拷贝构造函数、赋值运算符及其移动语义
class Array {
public:
// 构造函数
Array(int size) : m_size(size) {
m_data = new int[m_size];
cout << "struct funtion, m_data: " << m_data <<" size: "<< m_size << endl;
}
// 拷贝构造函数
Array(const Array& temp_array) {
m_size = temp_array.m_size;
m_data = new int[m_size];
for (int i = 0; i < m_size; i++) {
m_data[i] = temp_array.m_data[i];
}
cout << "copy struct funtion, m_data: " << m_data << " size: " << m_size << endl;
}
// 移动构造函数
Array(Array && rhs) {
m_size = rhs.m_size;
m_data = rhs.m_data;
rhs.m_data = nullptr;
cout << "move struct funtion, m_data: " << m_data << " size: " << m_size << endl;
}
// 赋值运算符
Array& operator=(const Array& temp_array) {
if (this != &temp_array) { // 避免自赋值
delete[] m_data;
m_size = temp_array.m_size;
m_data = new int[m_size];
for (int i = 0; i < m_size; i++) {
m_data[i] = temp_array.m_data[i];
}
cout << "=operator funtion, m_data: " << m_data << " size: " << m_size << endl;
}
return *this;
}
// 移动赋值运算符
Array& operator=(Array &&rhs) {
if (this != &rhs) { // 避免自赋值
m_size = rhs.m_size;
m_data = rhs.m_data;
rhs.m_data = nullptr;
cout << "move =operator funtion, m_data: " << m_data << " size: " << m_size << endl;
}
return *this;
}
~Array() {
delete[] m_data;
}
public:
int * m_data;
int m_size;
};
int main()
{
cout << "========赋值运算符&拷贝构造函数=========" << endl;
Array c(5); // 构造函数
Array c1(50); // 构造函数
Array d = c; // 拷贝构造函数
c1 = c; // 赋值运算符
cout << "========移动语义=========" << endl;
Array e1 = std::move(c); // 移动构造函数
Array e2(3); // 构造函数
e2 = std::move(c1); // 移动赋值运算符
return 0;
}
运行结果:
网友评论