22 考虑使用运算符的复合形式取代其单独形式

对于如下的代码:

x = x + y;   x = x - y;

也可以这样写:

x += y;  x -= y;

 如果x和y是用户自定义类型,就不能确保这样。就C++来说,operator+、operator=和operator+=之间没有任何关系,因为如果你想让这三个operator同样存在并具有你所期望的关系,你必须自己实现它们。同理operator-,*,/,等等一样。

确保operator的复合形式与一个单独形式之间存在正常的关系,一种好方法就是后者调用前者来实现:

//operator+根据operator+=来实现
const Rational operator+(const Rational& lhs,const Rational& rhs)
{
	return Rational(lhs) += rhs;
}
//operator-根据operator-=来实现
const Rational operator-(const Rational& lhs,const Rational& rhs)
{
	return Rational(lhs) -= rhs;
}

在这个例子中,从零实现了operator+=和-=,而operator+和operator-则是调用前面的函数来提供自己的功能。这种设计方法只用为何operator的复合形式就行了。如果operator复合形式在类的public接口里,这样不用让operator的单独形式成为类的友元。

如果你不介意把所有的operator单独形式放在全局域里,可以使用模板来替代单独形式的函数编写:

template<typename T>
const T operator + (const T& lhs,const T& rhs)
{
	return T(lhs) += rhs;
}

template<typename T>
const T operator - (const T& lhs,const T& rhs)
{
	return T(lhs) -= rhs;
}

这样编写不错,但是,没考虑效率问题。在这里指出三个效率问题:

  • 总的来说operator复合形式比单独形式效率高,因为单独形式要返回一个新的对象,从而在临时对象的构造和释放有一些开销,operator复合形式把结果写到左边的参数里,因此不需要临时对象来容纳operator的返回值。
  • 提供的operator的复合形式的同时也要提供其标准形式,允许类的客户端在便利和效率方面折中选择,客户可以这样写:
Rational a,b,c,d,result;
...
result = a + b + c + d;

还可以这样编写:

result = a;
result += a;
result += b;
result += c;
result += d;

 前者比较容易编写、debug和维护,并在80%的时间里它的性能可以被接受。后者具有更高的效率。

扫描二维码关注公众号,回复: 3039443 查看本文章
  • 涉及到operator的单独形式调用了T的拷贝构造函数。它建立了临时对象,其值与lhs一样。这个临时对象用来与rhs一起调用operator+=,操作符结构从operator+返回。这样会比起命名对象效率更高,使用了返回值最优化的方法(RVO)

总结:

operator的复合形式(operator+=)比单独形式(operator+)效率更加高。作为一个程序库的设计者,应该两者都提供,作为一个应用程序的开发者,在优先考虑性能时你应该考虑使用operator复合形式代替单独形式。

猜你喜欢

转载自blog.csdn.net/weixin_28712713/article/details/81324668
22