运算符重载

内容预览
运算符重载**
友元函数
一元运算符重载
重载 << 运算符*

正文

运算符重载(operator overloading)

  • 运算符重载 :就是“想法转换”,简化函数调用的方式

    把标准的函数使用方式,重新定义为自己认为的方式

     运算符重载就是赋予运算符新的含义,同一个运算符可以有不同的功能
     例如:
     		+号可以对不同类型int, float等数据进行加法操作
     		<< 既是位移运算符,又可以配合cout向控制台输出数据
     		C++本身已经对这些运算符进行了重载
    
  • demon

    定义一个运算符重载就像定义一个函数,函数名称已oprator关键字开头

    class Integer
    {
    public:
        Integer(): m_num(0){}
        Integer(int num): m_num(num){}
        const Integer operator+(const Integer & other) const
        {
            cout << "重载了运算符+,以便实现两个整型对象相加" << endl;
            return Integer(this->m_num + other.m_num);
        }    
    private:
        int m_num;
    };
    主程序
    Integer num1(1024);
    Integer num2(24);
    Integer num3 = num1 + num2;		
    

    注意:

    1.运算符重载的语法格式:
    返回类型 operator 被重载的运算符(参数列表)
    2.编译器实际调用:
    num3 = num1.operator+(num2);

    3.上图3个const:

      1.第一个const修饰函数返回值,使用const传递引用,提高效率
      2.第二个const修饰函数参数,参数在函数体内部不能改变
      3.第三个const修饰函数,不改变成员变量
    

在这里插入图片描述

  • 运算符重载列表
    在这里插入图片描述
    在这里插入图片描述
    友元函数

  • 友元函数

    运算符声明成类成员函数还是独立友元函数,建议准测:

     1.C++规定,赋值运算符=、数组下标运算符[ ]、函数调用运算符()、成员访问运算符->在重载时必须声明为类的成员函数
     2.流运算符<<、>>、类型转换运算符不能定义为类的成员函数,只能是友元函数
     3.一元运算符和复合赋值运算符重载时,一般声明类的成员函数
     4.二元运算符在运算符重载时,一般声明为友元函数
    
  • 应用场景

    在这里插入图片描述
    注意:

     1.对于很多运算符来说,可以使用成员函数或非成员函数来实现运算符重载;
     	一般来说,非成员函数应该是友元函数,这样才能直接访问类的私有数据。
     2.在定义运算符时,必须选择其中的一种格式,而不能同时选择这两种格式;
     	同时定义这两种格式将被视为二义性错误,导致编译错误。
     3.那么哪种格式最好呢?
     	对于某些运算符来说,成员函数是唯一合法的解释。其他情况下,这两种格式没有太大的区别。
     	根据类的设计,使用非成员函数版本可能更好(尤其是为类定义类型转换时)
    

赋值构造函数

  • 自定义string(字符串)类,以简化字符串的操作

    class String
    {
    public:
        String(char * str);
        friend ostream & operator<<(ostream & out, const String & str);
        String & operator=(String & str);
        virtual ~String();
    private:
        int length;     //字符串的实际长度(不包括\0)
        char * value;   //实际存储字符的字符数组
    };
    
    主程序
    
    String str1 = "爱吃酸辣土豆丝";
    String str2;
    str2 = str1;
    
     注意:
     如果我们不重载赋值运算符,对象str1的内容直接复制到新对象str2中。
     对于没有指针的简单类来说这足够了。
     但当我们拥有作为数据成员的指针时,逐字节的复制将会把指针从一个对象复制给另一个对象,而两个指针就会同时指向一个内存。
    
  • 解决方案:
    重载赋值运算符

    String & String::operator=(String & str)
    {
        delete[] value;     //首先释放字符串的默认空间
        length = strlen(str.value); //重新测量字符串长度
        value = new char[length + 1];
        strcpy(value, str.value);
        return *this;
    }
    
     注意:
     1.当重载赋值运算符时,务必确定将一个对象中的所有数据成员复制到另一个对象中
     2.如果包含多个数据成员,则每个成员都需要复制到目标对象中
    
  • 另一种状况

    复制、拷贝构造函数

     对于简单的类:
     	默认拷贝构造函数一般是够用的,没有必要再显式地定义一个功能类似的拷贝构造函数
     当类拥有其他资源时:
     	如动态分配的内存 、打开的文件、指向其他数据的指针、网络连接等,
     	默认拷贝构造函数就不能拷贝这些资源,必须显式定义拷贝构造函数,以完整地拷贝对象的所有数据
    

    应用场景
    在这里插入图片描述
    在下面三种场景中会调用复制构造函数:
    1.当类的对象被初始化为同一类的另一个对象时
    2.当对象被作为参数传递给一个函数时
    3.当函数返回一个对象时

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值