第六章 C++运算符重载(operator)

以下是本人整理的C++基础知识点,内容并不包含全面的C++知识,只是对C++重点内容、特点进行整理和归纳。

6.1 C++运算符重载介绍

运算符重载介绍
    功能
        运算符在不同情况下有不同的功能,在不同情况下执行不同的操作

    格式
        返回值类型 operator运算符名称(形参表列){...}
        operator
            关键字,用于定义重载运算符的函数
            可以将【operator 运算符名称】这一部分看做函数名


    C++中默认的运算符重载
        +
            对不同类型(int、float ..)的数据进行加法操作

        <<
            位移运算符
            输出流运算符,配合 cout 向控制台输出数据


    运算符重载的本质
        运算符重载是通过函数实现的,它本质上是函数重载

    运算符重载函数和普通函数的区别
        运算符重载函数除了函数名有特定的格式,其它地方和普通函数并没有区别


类内运算符重载和全局运算符重载
    类内运算符重载
        该重载只对该类的对象有效
        例子
            编译前:c3 = c1 + c2;
            编译后:c3 = c1.operator+(c2);  
            过程:编译器检测+号左边(+号是左结合性)是一个类对象,就会调用该类的成员函数:operator+()


    全局运算符重载
        例子
            定义:complex operator+(const complex &A, const complex &B){}
            编译前:c3 = c1 + c2;
            编译后:c3 = operator+(c1, c2);
            过程:编译器检测+号两边都是 complex 对象,则调用重载函数: operator+()



运算符重载例子
    例子1:类内运算符重载
        //+运算符重载,实现复数运算
        complex complex::operator+(const complex &A) const{
            complex B;
                B.m_real = this->m_real + A.m_real;
                B.m_imag = this->m_imag + A.m_imag;
            return B;
            }


    例子2:全局运算符重载
        //+运算符重载,实现复数运算
        complex operator+(const complex &A, const complex &B){
            complex C;
             C.m_real = A.m_real + B.m_real;
             C.m_imag = A.m_imag + B.m_imag;
            return C;
            }



运算符重载相比于函数的特点
    功能上,运算符重载和函数都能实现相同的功能
    使用上,运算符重载用于运算更加简洁,扩展了原有运算符的功能

6.2 C++运算符重载规则

1、并不是所有的运算符都可以重载
    可以重载的运算符
        +  -  *  /  %  ^  &  |  ~  !  =  <  >  +=  -=  *=  /=  %=  ^=  &=  |=  
        + <<  >>  <<=  >>=  ==  !=  <=  >=  &&  ||  ++  --  ,  ->*  ->  ()
        +   []  new  new[]  delete  delete[]

    不能重载运算符
        长度运算符 sizeof
        条件运算符 : ?
        成员选择符.
        域解析运算符::


 2、重载不能改变运算符的优先级和结合性
3、重载不会改变运算符的用法
    原有有几个操作数、操作数在左边还是在右边,这些不变

4、运算符重载函数不能有默认的参数
    否则就改变了运算符操作数的个数,否则就改变了运算符操作数的个数

5、运算符重载函数既可以作为类成员函数,也可以作为全局函数
    作为类成员函数
        二元运算符的参数只有一个,一元运算符不需要参数
        因为其中一个参数是隐含的,通过 this 指针隐式访问

    作为全局函数
        二元操作符就需要两个参数,一元操作符需要一个参数
        其中必须至少有一个参数是自定义类型的对象
            告知编译器使用自定义的运算符
            不能所有参数都是基本数据类型,否则会修改内置类型的运算符性质,这是禁止的!

        一般都需要在类中将该函数声明为友元函数
            这样函数才能在类外访问类的 private 成员



6、箭头运算符->、下标运算符[ ]、函数调用运算符( )、赋值运算符=只能以成员函数的形式重载

6.3 以成员函数还是全局函数(友元函数)的形式重载运算符

转换构造函数
    属于构造函数的一种。在初始化对象时,起到构造函数的作用;
    在运算中,能够用来将其它类型转换为当前类类型
    
    例子
        Complex(double real); //Complex类的构造函数
        Complex c1(25, 35);
        Complex c2 = c1 + 15.6;  //转换为Complex c2 = c1 + Complex (15.6);


以全局函数的形式重载运算符+的原因
    保证 + 运算符能够对称处理操作数
        Complex c2 = c1 + 15.6;//两者都准确,且结果相等
        Complex c2 = 15.6 + c1; //


成员函数形式重载,运算符左边的操作数必须是类对象,不能是其它类型
    因为运算时,会将左边操作数动作对象,调用该对象的重载函数;右边的操作数作为函数参数
    转换构造函数只会转换作为函数参数的那个操作数
        一般是运算符右边的操作数


如何选择这两种重载方式
    优先考虑成员函数,这样更符合运算符重载的初衷
    一部分运算符重载必须是全局函数,这样能保证参数的对称性

6.4 C++重载>>和<<(输入和输出运算符)

重载>>运算符
    istream & operator>>(istream &in, complex &A){//重载
         in >> A.m_real >> A.m_imag;  //本质上等于cin>> A.m_real >> A.m_imag; 
        return in; //返回cin对象,实现连续输入

    }
    complex c1, c2;
    cin>>c1>>c2;//使用

重载<<运算符
    ostream & operator<<(ostream &out, complex &A){
            out << A.m_real <<" + "<< A.m_imag <<" i ";

    return out; //返回cout对象,实现连续输出
    }

6.5 C++重载[]

特点
    只能以成员函数形式重载

语法
    返回值类型 & operator[ ] (参数);
        可访问可修改,const对象不能使用
        例子
            int& Array::operator[](int i){
            return m_p[i];
            }


    const 返回值类型 & operator[ ] (参数) const; 
        可访问不可修改,const对象能使用
        例子
            const int & Array::operator[](int i) const{
            return m_p[i];
            }



重载[ ]运算符以后
    转换前:arr[i]
    转换后:arr.operator[ ](i);

6.6 C++重载++和–(自增和自减运算符)

介绍
    自增++和自减--都是一元运算符,它的前置形式和后置形式都可以被重载

语法
    classType operator++();  //++i,前缀式自加
    classType operator++(int);  //i++,后缀式自加
        加int参数只做函数区分,没有实际意义

6.7 C++重载new和delete运算符

特点
    可以是类的成员函数,也可以是全局函数
    一般情况下,内建的内存管理运算符就够用了
    类中没有定义 new 和 delete 的重载函数,那么会自动调用内建的 new 和 delete 运算符

语法
    void * className::operator new( size_t size ){...}
        参数:申请内存的长度
        返回void*类型

    void * operator new( size_t size )( size_t size ){...}
    
    void className::operator delete( void *ptr){...}
        参数:void*型指针

    void operator delete( void *ptr){...}

6.8 C++重载()(强制类型转换运算符)

介绍
    类型的名字(包括类的名字)本身也是一种运算符,即类型强制转换运算符
    只能重载为成员函数,不能重载为全局函数
    编译器在认为需要类型转换时,就会隐式调用强制转换
    语法
        (类型名)对象,等价于对象.operator 类型名()

    例子
        double():double类型强制转换运算符
        double(i)就是调用内建的double类型强制转换运算符,将 i 转换为double,然后将结果返回


例子
    //重载double强制类型转换运算符
    operator double() { return real; }  //无需写返回类型
    //调用
    (double)c;  //强制转换c的类型
    double n = 2 + c; //等价于double n = 2 + c. operator double()

6.9 运算符重载注意事项

重载后运算符的含义,应该符合原有用法习惯

运算符可以重载为全局函数,然后声明为类的友元

必要时需要重载赋值运算符 =,以避免两个对象内部的指针指向同一片存储空间
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值