C++ Operators

就类而言,c++几乎没有预先定义的操作符。当使用类定义自己的类型时,往往希望能够有适用于这些自定义类型的操作。
当定义自己操作符时,需要写一个名字是operatorX的函数,X代表操作符,如operator+, operator是c++保留字。
1)基本上所有预定义的操作符都能够被重载。而且只有标准操作列表中的才能够被重载。
2)重载的操作符和预先定义的操作符应该有相同的操作数。例如,operator== 必须有两个操作数,operator! 必须是一个操作数。
3)如果某些操作符可能有不同情况(单操作数和双操作数,如-),则自己定义的版本中要包含这两种情况。
4) 自定义的操作和预先定义的操作遵循相同的优先级。
5)操作符可以用友元函数或成员函数来实现。通常用成员函数。

class Array {
public:
    bool operator==(const Array& v) const;
private:
    int *p;
    const int i1;
    int num;
};

上述定义中,operator==只有一个参数,而比较操作符必须要有两个参数。这是因为第一个参数将自动变成一个实际对象。例如:

v1 == v2

编译器将自动解释为:

v1.operator==(v2)

即函数operator==是作为v1的对象而被调用,而v2作为哑元。因此函数正式参数是v2,而this指针则指向v1. 因此,操作符作为成员函数时,二元操作符总有一个参数,一元操作符有0个参数。
注意以下:
1)以上定义时,我们暗示operator==是常函数,这是当然的,因为实际的对象在比较过程中不会被改变。
2)以上定义没有暗示参数v是类型Array,而是一个常Array的reference. 通过使用reference,避免了每次调用都要拷贝整个Array对象。另外,通过指明它是一个常数的reference,保证了右手边的操作数在比较过程中不会被改变。

单独来实现operator==. 两个Array对象相等,如果他们包含同样数目的元素,且每个元素等于依次相等。

bool Array::operator== (const Array& v) const
{
    if(num != v.num)
        return false;
    for(int i=0;i<num;i++)
        if(p[i] != v.p[i])
            return false;
    return true;
}

如果这个函数被调用:v1==v2. num将指的是v1中的num, v.num将指的是v2中的num.

再定义+=操作:

const Array& Array::operator+=(const Array& v)
{
    assert(num==v.num);
    for(int i=0;i<num;i++)
        p[i] += v.p[i];
    return *this;
}

同样,左边的操作数是个实际对象,参数v指的是右边操作数。由于右边的操作数不会改变,因此是常数的reference。 调用此函数时:

v1+=v2;

但此操作符也能是更复杂表达式中一部分:

if(v3==(v1+=v2))

因此operator+=应该能返回一个合理结果,以便能参与到operator==的操作。为达到此目的,operator+=应该返回一个左手边操作数的拷贝,此时即返回v1的新值的拷贝。因此,在定义时,我们指定结果类型是一个常Array的refernence. 在penultimate line(倒数第二行),指定返回*this. 通过暗示返回类型是reference,避免了无效的拷贝。
暗示返回结果类型是指向一个常数的reference很重要。自然的,不可能通过结果来改变一个实际对象。
下面看operator+

Array Array:: operator+ (const Array& v) const
{
    assert(num==v.num);
    Array temp(*this); //creat a copy of this array object
    temp += v;
    return temp;
}

这个函数中,不能再返回指向实际对象的reference作为结果,因为在operator+操作中对象不会被改变。相反,我们在函数中定义一个局部临时变量,并且用*this去初始化这个变量。其实*this就是实际Array的一个对象。因此Array对象temp将在copy constructor的帮助下初始化,将包含一个实际array对象的拷贝。如果调用函数v1+v2, temp将是v1的拷贝。然后在temp上用operator+=,改变它的值。
可能看起来很奇怪,因为我们既没有在this function中,也没有在operator+=中指定结果类型应该是reference. 如果我们这么做,函数将给给变量temp一个引用作为结果。这不正确,因为temp旨在函数operator+内存在,一旦函数完成,它将消失。我们知道reference是一种指向变量的指针。如果我们返回引用作为结果类型,因此我们事实上返回了一个lingering pointer (which points to a memory space allocated earlier but now deallocated )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值