zoukankan      html  css  js  c++  java
  • 十四章、重载操作符

    十四章、重载操作符

    一、重载操作符的定义: 保留字operator后接需要定义的操作符符号,同时具有返回类型和形参表;如:Sales_item operator+ (const Sales_item&,const Sales_item&);

    1、  除了函数调用操作符之外,重载操作符的形参数目与操作符的操作数数目相同,函数调用操作符可以接受任意数目的操作符。

    2、  重载操作符必须具有一个类类型操作数,内置类型的操作符其含义不能改变;(重载操作符必须具有至少一个类类型或枚举类型)

    3、  作为类成员的重载函数,有一个隐含的this形参,限定为第一个操作数(左操作数)。

    4、  Cout << item1 + item2 << endl; 这个表达式隐式调用了Sales_item operator+

    5、  重载操作符的设计:不要重载具有内置含义的操作符

    (1)       合成赋值操作符进行逐个成员赋值

    (2)       默认情况下,取地址操作符(&)和逗号操作符(,)在类类型对象上的执行与在内置类型对象上的执行一样。

    (3)       内置逻辑与(&&)和逻辑或(||)使用短路求值,如果重新定义该操作符,将失去操作符的短路求值特征。

    6、  为类设计操作符,最好的方式是首先设计类的公用接口。定义了接口之后就可以考虑将那些操作符定义为重载操作符。如:

    • ·相等测试操作应使用operator == ;
    • ·一般通过重载一位操作符进行行输入和输出;
    • ·测试对象是否为空的操作可以用逻辑非操作符operator!表示。

    7、  选择成员或非成员师兄:

    ·赋值(=)、下标([])、调用(())和成员访问箭头(->)等操作符必须定义为成员。

    ·复合赋值操作符通常定义为类的成员。

    ·自增或自减和解引用通常定义为类成员。

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

    二、输入和输出操作符:为了与IO标准库一致,操作符应接受ostream&/istream&作为顶一个形参,对类类型const对象的引用作为第二个行程,并返回ostream/istream形参的引用。

    1、  salse_item的输出操作符:

    • ostream& operator<<(ostream& out,const Sales_item& s)

    {

    Out << s.isbn << “\t” << s.units_sold << “\t” << s.revenue << “\t” << s.avg_price() ;

    Return out ;

    }

    (如果IO操作符是类成员,则左操作数将智能是该类类型的对象,所以必须为非成员函数,同时,类通常将IO操作符设为友元)

    2、  输入操作符 >> 重载:Sales_item 的输入操作符

    Istream& operator>> (istream& in ,Sales_item& s)

    {

             Double price;

             In >> s.ibsn >> s.units _sold >> price ;

             If (In)

                       s.revenue = s.units_sold * price ;

             else

                       s = Sales_item() ; 

    }

    输入期间的错误:

    (1)       任何读操作都可能因为提供的值不正确而失败。如读入isbn之后,输入操作符将期望下两项是数值型数据。如果输入非数值型数据,这次的读入以及流的后续将都是失败。

    (2)       任何读入都可能碰到输入流中的文件结束或其他一些错误。

    如果有错,具体做法是创建一个新的、未命名的、使用默认构造函数的Sales_item对象并将它赋值给s。赋值后,s的isbn是空string,revenue和units_sold为0.

    三、算术操作符和关系操作符:一般,将算术和关系操作符定义为非成员函数。

    1、  相等操作符:

    Inline bool operator==(const Sales_item &lhs,const  Sales_item &rhs)

    {

    Return lhs.units_sold == rhs.units_sold && lhs.revenue == rhs.revenue &&

    lhs.same_isbn(rhs) ;

    }

    Inline bool operator!=(const Sales_item &lhs, const Sales_item &rhs)

    {

     Return !(lhs == rhs) ;

    }

    函数所包含的设计原则:

    • ·如果类定义了==操作符,该操作符的含义是两个对象包含同样的数据。
    • ·如果类具有一个操作,能确定该类型的两个对象是否相等,通常将该函数定义为operator==,而不是创造命名函数。
    • ·如果类定义了operator==,应该也定义operator!=
    • ·相等和不相等操作符一般应该联系定义。一个完成对象操作,另一个只需要调用前者。如上面函数。

    四、赋值操作符: 赋值操作符必须定义为成员函数,必须返回对*试试的引用!

    五、下标操作符:类定义下标操作符时,一般需要两个版本:一个非const成员的返回引用,另一个const成员的返回const引用!

    1、  原型下标操作符: 简化,假定Foo所保存的数据储存在一个vector<int>中:

    Class Foo

    {

             Public:

                       Int  &operator[] (const size_t);

    Const  Int  &operator[] (const size_t)const ;

                       Private:

                                Vector<int> data;

    }

    下标操作符:

    Int & Foo::operator[] (const size_t index)

    {

     Return data[index] ;

    }

    Const int & Foo::operator[](const size_t index) const

    {

             Return data[index] ;

    }

    六、自增和自减操作符

    1、    ++I ,--I 形式:

    声明形式:

    Class CheckedPtr

    {

             Public:

                       CheckedPtr& operator++();

                       CheckedPtr& operator- -();

    } ;

    函数具体形式:

    CheckedPtr& CheckedPtr::operator++()

    {

             If(curr == end)

                       Throw out_of_range(”increment past the end of CheckedPtr”);出错处理

             ++cuur ;

             Return *this ;

    }      // ++i

    CheckedPtr& CheckedPtr::operator--()

    {

             If(curr == end)

                       Throw out_of_range(”increment past the end of CheckedPtr”);出错处理

             --cuur ;

             Return *this ;

    }      // --i

    2、    i++ / i—形式:

    声明形式:

    Class CheckedPtr

    {

             Public:

                       CheckedPtr& operator++(int);

                       CheckedPtr& operator- -(int);

    } ;

    为了区分++i和i++,将重载操作符函数增加了一个无用的int形参,一般可以传一个0进来。

    此时操作符应该返回旧值(尚未自增,自减的值),是值返回,而不是返回引用。

    CheckedPtr& CheckedPtr::operator++(int)

    {

             CheckedPtr ret(*this)         ;

    ++*this ;

             Return ret ;

    }      //  i++

    CheckedPtr& CheckedPtr::operator--(int)

    {

             CheckedPtr ret(*this)         ;

    --*this ;

             Return ret ;

    }      //  i--

  • 相关阅读:
    bzoj3721
    [BZOJ3555] [Ctsc2014]企鹅QQ(Hash)
    [POJ3233] Matrix Power Series(矩阵快速幂)
    矩阵运算所满足的定律
    [luoguP1962] 斐波那契数列(矩阵快速幂)
    [luoguP3390]【模板】矩阵快速幂
    【转】关于LIS和一类可以用树状数组优化的DP 预备知识
    [BZOJ1264][AHOI2006]基因匹配Match(DP + 树状数组)
    [luoguP1439] 排列LCS问题(DP + 树状数组)
    蛤蛤蛤(树状数组 | 二分)
  • 原文地址:https://www.cnblogs.com/ss815367696/p/2597597.html
Copyright © 2011-2022 走看看