操作符重载

一、操作符函数重载
 什么是操作符函数:在C++中针对类类型的对象的运算符,由于它们肯定不支持真正的运算操作,因此编译器会将它们翻译成函数,这种就叫作操作符函数(运算符函数)。
 编译器把运算翻译成运算符函数,可以针对自定义的类类型设计它独有的运算功能。
 其实各种运算已经具备一些功能,再次实现它的就是叫作运算符重载。
 
 双目运算符:
  a+b
  成员函数
   a.operator+(b);
  全局函数
   operator+(a,b);
 单目运算符:
  !a
  成员函数
   a.operator!(void);
  全局函数
   operator!(a);
二、双目操作符函数重载
 成员函数:
 const 类 operator#(const 类& that) const
 {
  return 类(参数#参数);
 }
 
 注意:双目录运算符的运算结果是个右值,返回值应该加 const,然后为了const对象能够调用参数应写 const,函数也应该具备 const 属性。
 
 全局函数:
 const 类 operator#(const 类& a,const 类& b)
 {
 
 }
 注意:全局函数不是函数,可能会访问类的私有成员,解决这种问题可以把函数声明为类的友元函数(友元不是成员)。
 
 友元:在类的外部某个函数中想访问类的私有成员(public/protected/private)时,需要所在的函数声明为友元,但友元只是朋友,因此它只有访问权,没有实际的拥有权(其根本原因是它没 this 指针)。
 
 友元声明:把函数的声明写一份到类中,然后在声明前加上 friend 关键字,使用友元既可把操作符函数定义为全局的,也可以确保类的封装性。。
 
 注意:友元函数与成员函数不会构成重载关系,因为它们不在同一个作用域内。
 
三、赋值类型的双目操作符
 成员函数
  类& operator#(const 类& that)
  {
   
  }
 全局函数
  类& operator#(cosnt 类& a,const 类& b)
  {
  
  }
  
 1、获取单参构造成赋值运算的调用方式。
 String str = “sunll”; // 会调用单参构造,而不调用赋值运算符
 str = “hehe”;
 
 2、左操作数据不能具有 const 属性
  1、成员函数不能是常函数
  2、全局函数第一个参数不能有 const 属性
 
四、单目操作符函数重载
 成员函数
  const 类 operator#(void) const
  {
   
  }
 全局函数
  const 类 operator#(const 类& that)
  {
  
  }
  
 前++/–
  类& operator#(void)
  {
   
  }
  类& operator#(类& that)
  {
  
  }
  
 后++/–(哑元)
  const 类& operator#(int)
  {
   
  }
  const 类& operator#(类& that,int)
  {
  
  }
   
五、输入输出操作符重载
 cont 是 ostream 类型的对象,cin 是 istream 类型的对象。
 如果<</>>运算实现为成员函数,那么调用者应该是ostream/istream,而我们无权增加标准库的代码,因此输人/输出运算符只能定义为全局函数。
 
 ostream& operator<<(ostream& os,const 类& p)
 {
 
 }
 
 istream& operator>>(istream& is,类& p)
 {
 
 }
 
 注意:在输入输出过程中,cin/cout会记录错误标志,因此不能加 const 属性。
 
 
 
六、特殊操作符的重载
 1、下标操作符的重载[];常用于在容器类型中以下标方式获取元素。
 类型& operator[](int i)
 {
 
 }
 返回值应该是一个引用。
 2、函数操作符(),一个类如果重载函数操作符,那么它的对象就可以像函数一样使用,参数的个数与返回值类型可以不确定。它是唯一一个可以参数有缺省的操作符。
 3、解引用运算符 ,成员访问操作符 ->
 如果一个类重载了
和->,那么它的对象就可以像指针一样使用
 所谓的智能指针就是一种类对象,它支持解引用和成员访问操作符
 4、智能指针
  常规指针的确定:
   当一个常规指针离开它的作用域时,只有该指针所占用的空间会被释放,而它指向的内存空间能否被释放不确定,在一些特殊情况下(人为/业务逻辑的特殊性)free或delete没有执行。就会形成内存泄露
  智能指针的优点
   是一种封装了常规指针的类类型对象,当它离开作用域时,它的析构函数会自动执行,它的析构函数会负责释放常规指针所指向的动态内存(以正确方式创建的智能指针,它的析构函数才会正确执行)
  相同点:
  都支持*和->运算
  不同点:
  任何时候一个对象只能使用一个智能指针来指向,而常规指针可以指向多次
  智能指针的赋值操作需要经过拷贝构造/赋值构造特殊处理(深拷贝)
  
  auto_ptr:标准库中封装好的智能指针,实现了常规指针的基本功能
  头文件:
   用法:auto_ptr<指向的类型> 指针变量名(对象的地址)
  auto_ptr的局限性:
   不能跨作用域使用,一旦离开作用域指针变量会释放,它指向的对象也会释放
   不能放入标准容器
   不能指向对象数组
 5、new/delete/new[]/delete[]运算符重载
 1、C++缺省的堆内存管理器速度较慢,重载 new/delete 底层使用 malloc/free可以提高运行速度。
 2、new在失败时会产生异常,而每次使用new时为了安全都应该进行异常捕获,而重载new操作符只需要在操作符函数中进行一次错误处理即可
 3、一些占字节数比较小的类,频繁使用new,可能会大量的内存碎片,而重载new操作符后,可以适当的扩大每次申请的字节数,减少内存碎片产生的几率
 4、重载 new/delete 可以记录堆内存使用的信息
 5、重载 delete 可以检查到释放内存失败的信息,检测到内存泄露。
 
 
 
关于操作符重载的建议:
 1、在重载操作符时要根据操作符实际的功能和意义来确定具体参数,返回值,是否具有 const 属性,返回值是否是引用或者是临时对象。
 2、重载操作符要符合情理(要有意义),要以实际用途为前提前。
 3、重载操作符的意义是为了让对象的操作更简单、方便、提高代码可读性,而不是为了炫技。
 ++n;
 4、重载操作符要与默认的操作符的功能、运算规则一直,不要出现反人类的操作
七、重载操作符的限制
 1、不能进行重载的操作符:
  域限定符 ::
  直接成员访问操作符 .
  条件表达式 ?:
  字节长度操作符 sizeof
  类型信息操作符 typeid
 2、重载操作符不能修改操作符的优先级
 3、无法重载所有基本类型的操作符运算符
 4、不能修改操作的参数个数
 5、不能发明新的操作符

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值