在c++程序中,我们已知x=x+y 可以写成x+=y;但是在C++中,operator+,operator=和operator+=之间并没有设立任何互动关系,所以如果你希望这3个操作符都存在并且有着你所期望的互动关系,你就必须自己来实现。同理-,*,/也是一样。
要确保操作符的复合形式和其独身形式之间的自然关系能够存在,一个好方法就是以复合形式为基础来实现独身形式。如:
Rational& operator+=(const Rational& rhs);
const Ratinal operator+(const Rational& lhs,const Rational& rhs)
{
return Rational(lhs)+=rhs;
}
此例中operator+=是从头做起的,而operator+是调用前者以供应它们所需的机能,采用这种设计,那么这些操作符之中就只有复合形式才需要维护。
采用上述方式就是根据效率来取舍的,主要从三方面来解释:
1.一般而言,复合操作符比独身版本效率要高,因为独身版本通常必须返回一个新对象,也就是必须要负担一个临时对象的构造和析构成本。至于复合版本则是直接将结果写入器左端自变量,所以不需要产生一个临时对象来放置返回值。
2.如果调用时才有一下两种手法:
Rational a,b,c,d,result;
result = a+b+c+d;
//或这样写
result=a;
result+=b;
result+=c;
result+=d;
前者较易撰写、调试、维护。后者效率较高。如果供应两种选择,你便允许客户以较易理解的操作符独身版本来发展程序并调试,同事仍保留“将独身版本用更有效的复合版本取代”的权利。
3.我们再看看独身版本的两个实现形式:
template<class T>
const T operator+(const T& lhs,const T& rhs)
{
return T(lhs) += rhs;
}
//第二版本
template<class T>
const T operator+(const T& lhs,const T& rhs)
{
T result(lhs);
return result+= rhs;
}
第一个版本和第二版本几乎一样,但是却有个重要的差异,第二版本中含有一个命名对象result,而第一版本中拥有返回值优化(return value optimization),虽然它的实现方式很诡异,但是去使得编译器具有最佳的效果。(自古以来都是匿名对象总是比命名对象更容易消除,所以当你面临命名对象和临时对象的抉择时,最好是选择临时对象。它绝不会比其命名对象耗用更多成本,反倒是极有可能降低成本。
结论:操作符的复合版本(operater+=)比对应的独身版本(oeperator+)有着更高效率的倾向。身为一位程序库设计者,你应该两者都提供,身为一位应用软件开发这,如果性能是重要因素的话,你应该考虑以复合版本操作符代替其独身版本。