首先我们来看Object这个类,有以下几个成员函数:
class Object
{
private:
int value;
public:
Object(int x = 0) :value(x)//构造函数
{
cout << "Create Object" << this << endl;
}
Object(const Object& obj) :value(obj.value)//拷贝构造函数
{
cout << "copy Object" << this << endl;
}
~Object()//析构函数
{
cout << "Destroy Object" << this << endl;
}
Object& operator=(const Object& obj)//赋值运算符的重载函数
{
this->value = obj.value;
return *this;
}
};
先来解释一下运算符的重载函数为什么它的返回值必须这个类的引用:通常情况下,在对对象进行操作时我们需要和对内置类型的变量的操作保持一致,比如说在int中可以对三个变量进行连续赋值,如下代码所示:
int main()
{
int a = 10, b = 20, c = 0;
c = a = b;
return 0;
}
同样的,我们也希望在对对象进行操作时可以进行对象的连续赋值,像下面这种情况:
int main()
{
Object a(10);
Object b(a);
Object c(0);
c = a = b;
//系统将本行代码改写为函数调动的形式
//c=a.operator=b;
//c=operator(&a,b);
//此时如果赋值运算符的重载函数的返回值是无类型(void)的,那么c这个对象接受不到这个函数的返回值,不能达到连续赋值的效果,但是内置类型却可以做到这一点,因此运算符的重载函数的返回值必须是一个类类型。
return 0;
}
说完运算符重载函数的返回值是一个类类型,接着来说其返回值是一个类类型的引用的优点:就拿上面a,b,c三个对象来说,return *this是返回a对象本身,返回时就不用在额外生成临时对象因此而提高效率。
在内置类型中,自赋值是没有任何意义的,在对象中也是一样的,即对象a=a,自己给自己赋值毫无意义可言,所以我们将上面的赋值运算符的重载函数可以改为如下形式:
Object& operator=(const Object& obj)
{
if (this != &obj)//这里的&是取地址
{
this->value = obj.value;
}
return *this;
}