读书笔记(C++)————【重载操作符与转换】

来源:互联网 发布:mac输入法 编辑:程序博客网 时间:2024/06/05 04:44
//14.重载操作符与转换//14.1 重载操作符的定义    //不能重载的操作符    ::  .*  .   ?:    //重载操作符必须具有至少一个类类型或枚举类型的操作数    //优先级和结合性是固定的    //不再具备短路求值特性,重载&&和||不是好做法    //作为类成员函数的重载函数,形参比操作数少一,隐含this形参作为第一个操作数    //一般将算数和关系操作符定义为非成员,而将赋值操作符定义为成员    //也可以像普通函数一样调用重载操作符函数    cout << operator+(item1,item2) << endl;    //等效    cout << item1 + item2 << endl    //尽量避免重载 , & && || 操作符    //若重载算数操作符(+),应同时重载复合赋值符(+=)    //必须定义为成员的操作符:= [] () ->//14.2 输入输出操作符    //Sale_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操作必须为非成员函数,因为左操作数必须是类类型对象    //Sale_item重载输入操作符    istream&    operator<<(istream& in, Sales_item& s)    {        double price;        in >> s.isbn >> s.units_sold >> price;        if(in)            s.revenue = s.unit_sold * price;        else            s = Sale_item();//input failed:reset object to default state        return out;    }    //相等操作符    inline bool    operator==(const Sale_item& c1,Sale_item& c2)    {        return c1.units_sold == c2.units_sold &&               c1.revenue == c2.revenue &&               c1.same_isbn(c2);    }    inline bool    operator!=(const Sale_item& c1,Sale_item& c2)    {        return !(c1 == c2);    }//14.4 赋值操作符    //赋值操作符可重载且必须返回*this引用//14.6 成员访问操作符    //#include <iostream>    using namespace std;    class A{    public:        void action(){            cout << "Action in class A!" << endl;        }    };    class B{        A a;    public:        A* operator->(){            return &a;        }        void action(){            cout << "Action in class B!" << endl;        }    };    class C{        B b;    public:        B operator->(){            return b;        }        void action(){            cout << "Action in class C!" << endl;        }    };    int main(int argc, char *argv[])    {        C* pc = new C;        pc->action();        C c;        c->action();        getchar();        return 0;    }    /*上面代码输出结果是:     *Action in class C!     *Action in class A!     *///14.7 自增操作符和自减操作符    //调用后置++需要给出一个整形实参    c.operator++(0);    //调用操作符()和函数对象,必须声明为成员函数。    class absInt    {        int operator()(int val)        {            return val > 0 : -val : val;        };    };//14.8.1 将函数对象用于标准算法    //函数对象比函数更灵活,容易修改程序以根据其他值进行测试。例:    //函数:    bool GT6(const string &s)    {        return s.size() >= 6;    }    vector<string>::size_type wc =            count_if(words.begin(),words.end(),GT6);    //函数对象:    class GT_cls    {    public:        GT_cla(int val = 0):bound(val){}        bool operator()(const string &s)        {            return s.size() >= bound;        }    private:        string::size_type bound;    };    cout << count_if(words.begin(),words.end(),GT_cla(6))         << " words 6 characters or longer" << endl;//14.8.2 标准库定义的函数对象#include<functional>    //表 14 - 3 标准库函数对象    类型                 函数对象                所应用的操作符算术函数对象类型    plus<Type>                   +                    minus<Type>                  -  //接受一个实参                    multiplies<Type>             *                    divides<Type>                /                    modulus<Type>                %                    negate<Type>                 -关系函数对象类型    equal_to<Type>               ==                    not_equal_to<Type>           !=                    greater<Type>                >                    greater_equal<Type>          >=                    less<Type>                   <                    less_equal<Type>             <=逻辑函数对象类型    logical_and<Type>            &&                    logical_or<Type>             |                    logical_not<Type>            !  //接受一个实参    //每个类都定义了应用名操作的调用操作符    plus<int> intAdd;    int sum = intAdd(10,20);//sum = 30;    //函数对象常用于覆盖算法使用的默认操作符。例如,sort默认使用    //operator<按升序对容器进行排序。为了按降序对容器进行排序,    //可以传递函数对象greater。该类将产生一个调用操作符,调用基础对象的大于操作符。    //如果svec是一个vector<string>对象,以下代码将降序排列    sort(svec.begin(),svec.end(),greater<string>());//14.8.3 函数对象的函数适配器    //两类:1.绑定器  bind1st   bind2nd    //      2.求反器   not1(求反一元函数对象真值)    not2(求反二元函数真值)    //计算一个容器中所有小于或等于10的值,适配器返回一个函数对象    count_if(vec.begin(),vec,end(),bind2nd(less_equal<int>(),10)));    count_if(vec.begin(),vec,end(),not1(bind2nd(less_equal<int>(),10))));//14.9.2 转换操作符    //不允许转换数组或函数,可转换为指针以及引用    class SmallInt    {    public:        SmallInt(int i = 0):val(0)        {            if(i < 0 || i > 255)                throw std::out_of_range("Bad SmallInt Initialize")        }        operator int() const{return val;}    private:        std::size_t val;    };    //使用类类型转换    SmallInt si;    double dval;    si >= dval;   //si converted to int and then convert to double    if(si)      //si converted to int and then convert to bool    //只能应用一个类类型转换    //它可以转换为SmallInt,但不能转换成Int    class Intergral    {        Intergral(int i = 0):val(i){}        operator SmallInt() const {return val % 256;}    private:        std::size_t val;    };    int calc(int);    Integral inVal;    SmallInt si(intVal);    //ok    int i = calc(si)        //ok    int j = calc(intVal)    //error    //标准转换可放在类类型转换之前//14.9.3 实参匹配和转换    //待续    //    //    //    //    //    //    //    //    //    //    //    //    //    //    //    //    //    //    //    //    //    //    //    //    //
0 0
原创粉丝点击