分类:
2008-10-14 15:01:08
为什么要在operator=中返回"*this"的引用
作者:
[问题的提出]:
在很多书籍和文章中,很多次提到在对赋值操作符(=)进行重载的时候,要返回对目的(调用)对象实例(*this)的引用。其中不免有这样的论断:一定要返回对调用对象的引用;返回对调用实例对象的引用是为了实现链式连续赋值。
这里说明两个问题:第一,是否重载赋值操作符必须返回对调用对象的引用,第二,是否这样就可以实现链式赋值,而不这样就不行。
首先,必须承认,返回对"*this"的引用是标准的二目操作符重载的格式,效率很高。这样做有很多优点:如实现链式赋值、避免临时对象的产生(调用拷贝构造函数)、销毁(调用析构函数),但不是非这样做不可,下面通过对比来论述返回对"*this"的引用的优点及其他做法的缺点,同时也能清楚第二个问题,我们从例子着手。
// a.h class A { public: A(); A(int nTest); A(const A& a); virtual ~A(); A operator=(const A& a); // A& operator=(const A& a); private: int m_nTest; public: void printit(); }; } // a.cpp A::A(int nTest) { m_nTest = nTest; cout << "constructor A Value is executed now!" << endl; } A::A(const A& a) { this->m_nTest = a.m_nTest; cout << "Copy constructor A is executed now!" << endl; } A::A() { cout << "constructor A Default is executed now!" << endl; } A::~A() { cout << "Destructor A is executed now!" << endl; } A A::operator=(const A& a) // A& A::operator=(const A& a) { if (this==&a) return *this; this->m_nTest = a.m_nTest; cout << "Assignment A is executed now!" << endl; return *this; }在main()函数中调用
A a(100),b(99),c(98); a = b = c; a.printit(); b.printit(); c.printit();结果为:
constructor A Value is executed now! constructor A Value is executed now! constructor A Value is executed now! Assignment A is executed now! Copy constructor A is executed now! Assignment A is executed now! Copy constructor A is executed now! Destructor A is executed now! Destructor A is executed now! 99 99 98 Destructor A is executed now! Destructor A is executed now! Destructor A is executed now! |
constructor A Value is executed
now! constructor A Value is executed now! constructor A Value is executed now! Assignment A is executed now! Assignment A is executed now! 98 98 98 Destructor A is executed now! Destructor A is executed now! Destructor A is executed now! |
[2] 在赋值函数为:A& operator=(const A& a)的情况下
不同的是没有临时对象的产生,因为operator=返回的是对当前对象的引用,而引用只是别名,而不是构造新对象的。这点可以通过如下函数调用来理解:
void fun(A& temp)
{
temp ...
}
A a;
执行fun(a)函数调用时,没有产生临时对象。
可见,重载"="操作符,不一定要返回对赋值目的对象的引用,但返回引用是很好的做法,建议您这样使用。
最后提出几个问题,大家可以思考一下:
[1] 若将a=b=c; 改为(a=b)=c后分别调用A operator=(const A& a) 和A&operator=(const
A& a)结果会有什么不同?
[2] 能否将A&operator=(const A& a)改为const A&operator=(const A& a)?
[3] 能否将A&operator=(const A& a)中的return *this;改为return a?
[4] A a, b;
a = b;
与 A a;
A b = a; 有什么不同?
水平有限,欢迎大家批评指正!