运算符重载机制(下篇)

1 大型对象


我们将Complex的运算符都定义为以类型Complex为参数,对于Complex运算符,各个运算对象都需要复制。然而对于大型对象来说,复制时的开销是很恐怖的,所以为了避免过度复制,我们有两个解决办法:
1 定义以引用为参数的函数。
例如:
class Matrix{
public:
      friend Matrix operator(const Matrix &,const Matrix &);
};

引用时我们能对大型对象使用所涉到各种常见运算符的表达式,而又能避免过度复制。在这里不能使用指针,因为不能针对指针重定义运算符的意义。返回值是对象的引用,看起来合法,并且更加有效,然而这样做却会带来存储分配问题。一个结果的引用将被函数作为到返回值的引用传出来。这个返回值不能是自动变量,因此解决上述问题我们可以使用下面一种方法。
2 采用一个静态对象缓冲区,避免复制结果。
const int Max_size = 10;
Matrix &get_Matrix(){
      static int nbuf = 0;
      static Matrix buf[Max_size ];
      if(nbuf == Max_size )nbuf = 0;
      return buf[nbuf++];
}

Matrix & operator + (const Matrix &arg1,const Matrix & arg2){
      Matrix &res = get_Matrix();
      //............
      return res;
}

现在只有表达式的结果赋值时需要复制Matrix,当然,要是写出一个表达式,其中涉及临时变量多余Max_size ,只有老天能帮你了。

2两个有意思的东西


1 间接 
间接运算符->可以被定义为一个一元的后缀运算符。直接看例子:
class X{
public:
      int m;
};

class ptr{
      X *tmp;
public:
      //.........
      X* operator->(){
             return tmp;
      }
      void f(ptr p){
            p->m  = 7; //(p.operator->())->m = 7;
      }
};

看上去m就跟ptr的成员一样,是不是很有意思?

2  另一个很有意思的事情是如何实现a**b等价于a的b次方
上面的式子可以这样看 a*(*b)。

class B{
      int a1;
public:
      friend int operator *(B &tmp){
            return tmp.a1;
      }
};

class A{
      int a2;
public:
      operator int(){return a2;}
      friend int operator *(int a, int b){
           return pow(a,b);
      }
};

A   a;
B   b;
a ** b //a的b次方

有意思归有意思,但是不推荐这样做。因为这样做了会造成代码的阅读困难,在重载运算符的时候,我们最好不要有违它原来的意思。

最后


本文并没有介绍各种运算符的具体重载办法,而侧重于运算符重载编程中应该注意的东西,所以不适合没有代码经验基础的人阅读。如果你也跟我一样,对敲代码有浓厚的兴趣,欢迎讨论。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值