zoukankan      html  css  js  c++  java
  • C++ primer 第14章 重载操作符与转换

    重载操作符:具有特殊名称的函数,保留字operator后接需要定义的操作符符号

    Sales_item operator+(const Sales_item&,const Sales_item&);//声明了Sales_item类间的加法操作

    重载操作符必须具有至少一个类类型枚举类型操作数;这条规则强制重载操作符不能重新定义用于内置类型对象的操作符定义,即:

    int operator+(int,int);//error 错误的

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

    type operator ()(....,int i=100,.......){ 
    .......... 
    } 
    
    type operator +(....,int i=100/*error*/){ 
    .......... 
    }

    重载一元操作符,如果作为成员函数没有(显示)形参,如果作为非成员函数有一个形参。类似的,重载二元操作符,如果定义为成员函数,有一个形参,如果非成员函数有两个形参

    一般将算数和关系操作符定义为成员函数,将赋值操作符定义为成员;如:

    // member binary operator::left-hand operand bound to implicit this pointer  ;关键this指针,指向左操作数
    Sales_item& Sales_item :: operator +=(const Sales_item&);
    
    //nomember binary operator:must declare a parameter for each operand
    Sales_item operator +(const Sales_item&,const Sales_item&);                 算数操作符加号返回一个右值,而复合赋值 +=返回对左操作数的引用

    操作符重载定义为非成员函数时,通常必须将其设置为所操作类的友元:

    class Sales_item{
           friend std::istream& operator >>(std::istream&,std::istream&)
           public:
            Sales_item& operator+=(const Sales_item&)};


     

    短路求值:&&与||,只要确定最后结果为真或假,求值过程便终止。

    IO操作符必须为非成员函数,否则做操作数只能是该类类型的对象:

    //如果<<是Sales_item的成员,则
    Sales_item item;
    item<<cout; //与实际的cout相反

    IO操作符通常对非公用数据成员进行读写,所以,类通常将IO操作符设为友元

    输入操作符的第一个形参是引用,指向它要读的流,并且返回也是对同一个流的引用第二个形参是对要读入对象的const引用,必须是非const,因为最终目的是将数据读入到这个对象中。ps:因为要修改读入对象

    istream& operator>>(istream& in,Sales_item& s)
    {
       double price;
       in>>s.isbn>>s.units_sold>>price;
       if(in)
         s.revenue = s.units_sold*price;
       else
         s=Sales_item();
       return in;
    }

    设计输入操作符时,如果可能,要确定错误恢复措施

    算数操作符一般产生新值,所以重载返回值为一个新的类而不是类的引用,见P439

    赋值重载必须定义为成员函数,且必须返回对*this的引用;一般而言,赋值操作符与复合赋值操作符应返回左操作数的引用。

    Sales_item& Sales_item ::operator=(const Sales_item& rhs)
    {
       units_sold += rhs.units_sold;
       revenue += rhs.revenue;
       reurn *this;
    }


    下标操作符必须定义为类成员函数

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

    成员访问操作符:*,->;
    ->必须定义为类成员函数,*都可以
     
    ++,——操作符更倾向于定义为类成员。前增式操作符应返回被增量或被减量对象的引用后缀式返回旧值不返回引用),且用int来半段是否执行后缀式操作符。
    CheckedPtr& CheckedPtr::operator++()  //前缀式
    { 
       if(curr==end)
         throw out_of_range("increment past the end of CheckedPtr");
       ++curr;
       return *this;
    } 
    
    
    
    CheckedPtr CheckedPtr::operator++(int)   //后缀式,看形参int
    {
       CheckedPtr ret(*this);
       ++*this;
       return ret;
    }

    定义了调用操作符的类,起对象常称为函数对象,即他们是行为类似函数的对象。个人理解定义一个函数

    Struct  absInt{
      int operator() (int val){
          return val<0?-val:val;}
    };
    
    //.............
    int i=-42;
    absInt object;
    unsigned int ui = object(i);


    标准库定义了一组算数、关系与逻辑函数对象类,以及一组函数适配器,在functional头文件中定义。P453

    函数对象的函数适配器

    1.绑定器:将一个操作数绑定到给定值而将二元函数对象转换成一元函数对象。bind1st,bind2nd    P453

    2.求反器:将谓词函数对象的真值求反。not1,not2

    转换函数通用形式:operator type();  //特殊的类成员函数,不能指定返回类型 形参为空 ,不允许转换为数组或函数类型 *******

    class SmallInt{
      public:
        。。。
      operator int() const{return val} //不能指定返回类型,且无形参,一般函数转换不改变对象,所以采用const
      private:
      std::size_t val;
    }
  • 相关阅读:
    ztree——Cannot read property 'init' of undefined解决方案
    vue——手写swiper子组件,pagination不显示、轮播无效问题解决
    angularJS——数据更新了但是view(视图)层却未更新问题及解决方法
    vue——router.js动态注册组件
    js——ev || window.event,event.srcElement || event.target
    vue——keepAlive第一次无效问题及解决方法
    vue——列表页进详情页,第一次很慢,第二次就很快问题及解决方法
    vue——按需引入elementUI(以时间选择器为例)
    vue——预先指定高度,进行懒加载
    sql 分页查询
  • 原文地址:https://www.cnblogs.com/nkxyf/p/2520300.html
Copyright © 2011-2022 走看看