zoukankan      html  css  js  c++  java
  • C++重载操作符学习

    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;
    }
  • 相关阅读:
    计算机视觉(ComputerVision, CV)相关领域的站点链接
    JS-网页中分页栏
    国内搜索大哥iOS面试题
    【iOS与EV3混合机器人编程系列之中的一个】iOS要干嘛?EV3能够更酷!
    Android多线程.断点续传下载
    【转】BeyondCompare软件使用
    【转】目前世界上最为流行的代码托管网站
    【转】为什么要用GIT而不是SVN
    【转】UBUNTU 下GIT的安装
    【转】雄鹰计划-卓越工程师炼成记
  • 原文地址:https://www.cnblogs.com/littlethank/p/2590802.html
Copyright © 2011-2022 走看看