由于对c++的重载符号一直不是很理解,此处参阅一些资料给出比较详细的解释,方便读者以及自己查阅。
此处有更详细的解释,但是其中关于 a = b = c执行顺序的解释不正确!
例1
#include<iostream>
#include<cstring>
using namespace std;
class MyStr
{
private:
char *name = NULL;
int id;
public:
MyStr() {cout << "default\n" << endl;}
MyStr(int _id, char *_name) //constructor
{
cout << "constructor" << endl;
id = _id;
name = new char[strlen(_name) + 1];
memcpy(name, _name, strlen(_name) + 1);
}
MyStr(const MyStr& str)
{
cout << "copy constructor" << endl;
id = str.id;
if (name != NULL)
delete name;
name = new char[strlen(str.name) + 1];
memcpy(name, str.name, strlen(str.name) + 1);
}
MyStr& operator =(const MyStr& str)//赋值运算符
{
cout << "operator =" << endl;
if (this != &str)
{
if (name != NULL)
delete name;
this->id = str.id;
int len = strlen(str.name);
name = new char[len + 1];
memcpy(name, str.name, strlen(str.name) + 1);
}
return *this;
}
~MyStr()
{
delete name;
}
};
int main()
{
MyStr str1(1, "hhxx");
cout << "====================" << endl;
MyStr str2;
str2 = str1;
cout << "====================" << endl;
MyStr str3 = str2;
return 0;
}
结果1
constructor
====================
default
operator =
====================
copy constructor
此处可以看到执行
str2 = str1
时,调用了赋值运算符重载函数,可以与普通的函数调用一样理解,str2为函数调用者,str1为函数调用的参数(类似于str2.xxx(str1))。
赋值运算符重载函数形参为引用,避免了一次对象的拷贝构造。
同样,复制运算符重载函数函数返回值为引用,同样避免了一次对象的拷贝构造。若返回值类型为MyStr,那么在函数返回时,将构造一个linshi变量,并this指针指向的对象拷贝至该临时变量。
当然,也可以不返回任何对象,设置返回值为void。但是,返回对象或者引用时可以实现连续赋值,类似于a = b = c,等价于a = (b = c);
例2(将返回类型改为MyStr)
#include<iostream>
#include<cstring>
using namespace std;
class MyStr
{
private:
char *name = NULL;
int id;
public:
MyStr() {cout << "default\n" << endl;}
MyStr(int _id, char *_name) //constructor
{
cout << "constructor" << endl;
id = _id;
name = new char[strlen(_name) + 1];
memcpy(name, _name, strlen(_name) + 1);
}
MyStr(const MyStr& str)
{
cout << "copy constructor" << endl;
id = str.id;
if (name != NULL)
delete name;
name = new char[strlen(str.name) + 1];
memcpy(name, str.name, strlen(str.name) + 1);
}
MyStr operator =(const MyStr& str)//赋值运算符
{
cout << "operator =" << endl;
if (this != &str)
{
if (name != NULL)
delete name;
this->id = str.id;
int len = strlen(str.name);
name = new char[len + 1];
memcpy(name, str.name, strlen(str.name) + 1);
}
return *this;
}
~MyStr()
{
delete name;
}
};
int main()
{
MyStr str1(1, "hhxx");
cout << "====================" << endl;
MyStr str2;
str2 = str1;
cout << "====================" << endl;
MyStr str3 = str2;
return 0;
}
结果2
constructor
====================
default
operator =
copy constructor
====================
copy constructor
执行
str2 = str1
时,函数返回的是对象,调用拷贝构造函数产生一个临时变量。
例3(验证 a = b = c执行顺序)
#include<iostream>
#include<cstring>
using namespace std;
class MyStr
{
private:
char *name = NULL;
int id;
public:
MyStr() {cout << "default\n" << endl;}
MyStr(int _id, char *_name) //constructor
{
cout << "constructor" << endl;
id = _id;
name = new char[strlen(_name) + 1];
memcpy(name, _name, strlen(_name) + 1);
}
MyStr(const MyStr& str)
{
cout << "copy constructor" << endl;
id = str.id;
if (name != NULL)
delete name;
name = new char[strlen(str.name) + 1];
memcpy(name, str.name, strlen(str.name) + 1);
}
MyStr& operator =(const MyStr& str)//赋值运算符
{
if(name != NULL)
cout << name << " = " << str.name << endl;
cout << "operator =" << endl;
if (this != &str)
{
if (name != NULL)
delete name;
this->id = str.id;
int len = strlen(str.name);
name = new char[len + 1];
memcpy(name, str.name, strlen(str.name) + 1);
}
return *this;
}
~MyStr()
{
delete name;
}
};
int main()
{
MyStr str1(1, "str1");
cout << "====================" << endl;
MyStr str2(2, "str2"), str3(3, "str3");
str3 = str2 = str1;
cout << "====================" << endl;
MyStr str4 = str2;
return 0;
}
结果3
constructor
====================
constructor
constructor
str2 = str1
operator =
str3 = str1
operator =
====================
copy constructor
可以看到,首先构造是三个对象,name分别为str1, str2, str3。然后执行
str3 = str2 = str1
时,先是执行str2 = str1,对象str2获取str1的name之后,str3将获取str2新获取的name。