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

本文详细介绍了C++中的操作符重载概念及其应用场景,包括重载操作符的定义限制、常见操作符如算数操作符和赋值操作符的重载方式,以及输入输出操作符的重载实现。此外还探讨了自增自减操作符、成员访问操作符的重载方法,并介绍了函数对象和标准库定义的函数对象的应用。
//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 实参匹配和转换

    //待续

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //

    //
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值