C++重载操作符学习

爷,独闯天下 提交于 2020-04-02 09:38:15

1、通过连接其他合法符号可以创建新的操作符。

2、除了函数调用操作符operator()之外,重载操作符时使用默认实参是非法的。

3、重载操作符的形参数目(包括成员函数的隐式this指针)与操作符的操作数数目相同,函数调用操作符可以接受任意数目的操作数。

4、作为类成员的重载函数,其形参看起来比操作数数目少1.作为成员函数的操作符有一个隐含的this形参,限定为第一个操作数。

5、如果不定义,编译器将会合成的操作符有:赋值操作符(=)、取地址操作符(&)、逗号操作符(,)、&&和||。重载之后的&&和||不再具有短路特征。

6、选择成员或非成员实现的几点经验原则:

l  赋值(=)、下标([])、调用(())和成员访问箭头(->)等操作符必须定义为成员,将这些操作符定义为非成员函数将在编译时标记为错误。

l  像赋值一样,复合赋值操作符通常应定义为类的成员。与赋值不同的是,不一定非得这样做,如果定义非成员符合赋值操作符,不会出现编译错误。

l  改变对象状态或与给定类型紧联系的其他一些操作符,如自增、自减和解引用,通常应定义为类成员。

l  对称的操作符,如算术操作符、相等操作符、关系操作符和位操作符,最好定义为普通非成员函数。

7、不能滥用转换函数,应该只有一个内置类型的转换

 

下面是自己写的实现:

#ifndef INT_H
#define INT_H

#include <iostream>


using namespace std;

class INT
{
public:
    //因为定义了转换操作符,如果不禁止接受int形参的构造函数隐式转换的话,
    //将产生重定义的效果,例如表达式 INT i; i + 1.0f;
    //这样将不知道是将1.0f转换为1再调用构造函数,还是将i转换为float类型
    explicit INT(int i = 0);

    //下面的函数由编译器产生的已经可以达到我们的目标,故不定义
    //INT(const& INT);
    //~INT();

    //为了与IO标准库一致,操作符应接受ostream&作为
    //第一个形参,对类型const对象的引用作为第二个形参,
    //并返回对ostream形参的引用,而且必须为非成员函数
    //因为会访问到类的私有成员函数,所以声明为友元
    friend ostream& operator<<(ostream& out
        , const INT& r);

    //输入操作符的第一个形参是一个引用,指向它要读的流,并且返回的为同一个流的引用。
    //与输出操作符不同的是,第二个形参为非const引用(当然,输出操作符也不一定是const的引用)
    //那是因为输入操作符的目的是将数据读到这个对象中
    //!输入操作符必须处理错误和文件结束的可能性(这里为简单起见,则不处理)
    friend istream& operator>>(istream& in, INT& r);

    //复合赋值操作符
    INT& operator+=(const INT& r);
    INT& operator-=(const INT& r);
    INT& operator*=(const INT& r);
    INT& operator/=(const INT& r);

    /*按照经验原则,一般把对称的操作符定义为非成员函数*/
    //直接用复合赋值操作符来实现算术操作符,可以不必创建和撤销一个临时变量来保存结果(还没理解,
    //不知道怎么样的实现才可以不用这一步)
    //算术操作符可以不是友元函数,如果用符合赋值操作符实现的话
    friend INT operator+(const INT& l, const INT& r);
    friend INT operator-(const INT& l, const INT& r);
    friend INT operator*(const INT& l, const INT& r);
    friend INT operator/(const INT& l, const INT& r);

    /*按照经验原则,一般把对称的操作符定义为非成员函数*/
    friend bool operator==(const INT& l, const INT& r);
    friend bool operator!=(const INT& l, const INT& r);
    friend bool operator<(const INT& l, const INT& r);
    friend bool operator<=(const INT& l, const INT& r);
    friend bool operator>(const INT& l, const INT& r);
    friend bool operator>=(const INT& l, const INT& r);
    
    //赋值操作符,如果不定义一个赋值操作符,编译器将会合成一个,
    //所以必须定义为成员函数,参数一般为类类型的const引用
    INT& operator=(const INT&);
    INT& operator=(int);

    //转换操作符
    //转换函数通用形式为operator type();
    //转换函数必须是成员函数,不能指定返回类型,但是必须显示返回一个指定类型的值,
    //并且形参表为空(象征性的定义了float型的,其他的类似)
    operator float() const { return static_cast<float>(_value); }
    //构造函数接受了一个int的构造函数,故不应该定义int的转换函数
    //operator int() const { return _value; }

    /*按照经验原则,一般把改变对象状态的操作符定义为类成员*/
    //为了与内置类型一致,前缀式操作符应返回对象的引用
    INT& operator++();  //prefix operators
    INT& operator--();  //prefix operators
    //为了区分是后缀式还是前缀式,给后缀式加一个int参数,int参数只是起区分作用
    //后缀式可以用前缀式来实现,且返回值一般为值
    INT operator++(int); //postfix
    INT operator--(int); //postfix

private:
    int _value;
};

#endif
#include "INT.h"
#include <iostream>

std::ostream& operator <<(std::ostream &out, const INT &r)
{
    out << r._value;

    return out;
}

istream& operator >>(istream& in, INT& r)
{
    in >> r._value;

    return in;
}

INT operator+(const INT& l, const INT& r)
{
    INT ret(l);
    ret += r;

    return ret;
}

INT operator-(const INT& l, const INT& r)
{
    INT ret(l);
    ret -= r;

    return ret;
}

INT operator*(const INT& l, const INT& r)
{
    INT ret(l);
    ret *= r;

    return ret;
}

INT operator/(const INT& l, const INT& r)
{
    INT ret(l);
    ret /= r;

    return ret;
}

bool operator==(const INT& l, const INT& r)
{
    return l._value == r._value;
}

bool operator!=(const INT& l, const INT& r)
{
    return !(l == r);
}

bool operator<(const INT& l, const INT& r)
{
    return l._value < r._value;
}

bool operator<=(const INT& l, const INT& r)
{
    return (l < r) || (l == r);
}

bool operator>(const INT& l, const INT& r)
{
    return !(l <= r);
}

bool operator>=(const INT& l, const INT& r)
{
    return !(l < r);
}

//////////////////////////////////////////////////////////////

INT::INT(int i)
{
    _value = i;
}

INT& INT::operator =(const INT & r)
{
    _value = r._value;
    
    return *this;
}

INT& INT::operator =(int r)
{
    _value = r;

    return *this;
}

INT& INT::operator +=(const INT &r)
{    
    _value += r._value;

    return *this;
}

INT& INT::operator -=(const INT &r)
{    
    _value -= r._value;

    return *this;
}

INT& INT::operator /=(const INT &r)
{    
    _value /= r._value;

    return *this;
}

INT& INT::operator *=(const INT &r)
{
    _value *= r._value;

    return *this;
}

INT& INT::operator ++()
{
    ++ _value;

    return *this;
}

INT& INT::operator --()
{
    -- _value;

    return *this;
}

INT INT::operator ++(int)
{
    INT ret(*this);
    ++*this;

    return ret;
}

INT INT::operator --(int)
{
    INT ret(*this);
    --*this;

    return ret;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!