C++类—重载操作符

原创 2014年09月29日 16:13:00

 重载操作符是具有特殊名称的函数:保留字operator后接定义的操作符符号。如:

  1. Sales_item operator+(const Sales_item &,const Sales_item &);  

除了函数调用操作符之外,重载操作符的形参数目(包括成员函数的隐式this指针)与操作符的操作数数目相同

重载操作符必须具有一个类类型操作数,重载操作符必须具有至少一个类类型或枚举类型的操作数。这条规则强制重载操作符不能重新定义用于内置类型对象的操作符的含义。

 用于内置类型的操作符,其含义不能改变:

  1. int operator+(int,int); //Error  
  在&&||的重载版本中,两个操作数都要进行求值,而且对操作数的求职顺序不做规定。因此,重载&&||和逗号操作符不是一种好的做法


作为类成员的重载函数,其形参看起来比操作数数目少1作为成员函数的操作符有一隐含的this形参指针,限定为第一个操作数

   一般将算术和关系操作符(“对称”操作符)定义为非成员函数,而将赋值操作符定义为成员:

  1. Sales_item &Sales_item::operator+=(const Sales_item &);  
  2. Sales_item operator+(const Sales_item &,const Sales_item &);  

   当操作符为成员函数时,this指向左操作数,因此即使复合赋值是二元操作符,成员复合赋值操作符也只接受一个(显式的)形参。使用操作符时,一个指向左操作数的指针自动绑定到this,而右操作符限定为函数的唯一形参。


操作符重载和友元关系

   操作符定义为非成员函数时,通常必须将它们设置为所操作类的友元,因为操作符通常需要访问类的私有部分

  1. class Sales_item  
  2. {  
  3.     friend std::istream &operator>>(std::istream &,Sales_item &);  
  4.     friend std::ostream &operator<<(std::ostream &,const Sales_item &);  
  5.   
  6. public:  
  7.     Sales_item &operator+=(const Sales_item &);  
  8. };  
  9.   
  10. //不需要将加操作符设置为友元,它可以用public成员operator+=实现  
  11. Sales_item operator+(const Sales_item &,const Sales_item &);  

使用重载操作符

使用重载操作符的方式,与内置类型操作数上的使用操作符的方式一样。

    1)假定item1和 item2是 Sales_item对象,可以打印它们的和,就像打印两个int的和一样:

  1. cout << item1 + item2 << endl;  

    2)也可以像调用普通函数一样调用重载操作符函数:

  1. cout << operator+(item1,item2) << endl;  

    调用成员操作符函数与调用任意其他函数是一样的:指定运行函数的对象,然后使用点或箭头操作符获取希望调用的函数,同时传递所需数目和类型的实参。

  1. item1 += item2
  2. item1.operator+=(item2);

重载操作符的设计:

1、不要重载具有内置含义的操作符

   赋值操作符、取值操作符和逗号操作符对类类型操作数有默认含义。如果没有特定重载版本,编译器就定义一下这些操作符:

    1)合成赋值操作符进行逐个成员赋值:使用成员自己的赋值操作符依次对每个成员进行赋值。

    2)默认情况下,取地址操作符和逗号操作符在类类型对象上的执行,与在内置类型对象上的执行一样。取地址操作符返回对象的内存地址,逗号操作符从左至右计算每个表达式的值,并返回最右边操作数的值

    3)内置逻辑与(&&)与逻辑或(||)操作符使用短路求值。如果重新定义该操作符,将失去操作符的短路求值特性

【最佳实践】

    重载逗号、取地址、逻辑与、逻辑或等操作符通常不是好做法!这些操作符都具有拥有的内置含义,如果我们定义了自己的版本,就不能再使用这些内置含义!


    有时我们需要定义自己的赋值运算。这样做时,它应表现得类似于合成操作符:赋值之后,左右操作数的值应是相同的,并且操作符应返回对左操作数的引用。重载的赋值运算应在赋值的内置含义基础上进行定制,而不是完全绕开


2、大多数操作符对类对象没有意义

     除非提供了重载定义,赋值、取地址和逗号操作符对于类类型操作数没有意义

    为类设计操作符,最好的方式是首先设计类的公共接口。定义了接口之后,就可以只考虑应将哪些操作符定义为重载操作符。那些逻辑上可以映射到某个操作符的操作可以考虑作为候选的重载操作符。如:

    1)相等测试操作应使用operator=

    2)一般通过重载移位操作符进行输入和输出

    3)测试对象是否为空的操作可用逻辑非操作符operator!表示。


3、复合赋值操作符

    如果一个类有算术操作符或位操作符,那么,提供相应的复合赋值操作符一般是个好主意


4、相等和关系操作符

    将要用作关联容器键类型的类应定义<操作符,因为关联容器默认使用键类型的 <操作符即使该类型将只存储在顺序容器中,类通常也应该定义相等(==)和小于(<)操作符,理由是许多算法假定这个操作符存在。例如sort算法使用 <操作符,find算法使用 ==操作符。

    如果类定义了相等操作符,它也应该定义不等操作符!=。类用户会假设如果可以进行相等比较,则也可以进行不等比较。同样的规则也应用于其他关系操作符。如果类定义了<,则它可能应该定义全部的四个关系操作符(>,>=,<,<=)


5、选择成员或非成员实现

   1赋值=下标[]调用()成员访问箭头->等操作必须定义为成员,将这些操作符定义为非成员时会发生编译错误。

   2)像赋值一样,复合赋值操作符通常应该定义为类的成员。但是如果不这么做,也不会发生编译错误。

   3改变对象状态或与给定类型紧密联系的其他一些操作符,如自增自减解引用,通常定义为类成员。

   4对称的操作符,如算术操作符、相等操作符、关系操作符和操作符,最好定位普通非成员函数。


   当内置操作符和类型上的操作存在逻辑对应关系时,操作符重载最有用




C++ operator关键字(重载操作符)

重载运算符 operator是C++的关键字,它和运算符一起使用,表示一个运算符函数,理解时应将operator=整体上视为一个函数名。...
  • My_heart_
  • My_heart_
  • 2016年05月29日 22:55
  • 5012

C++ primer第二次阅读学习笔记(第14章:重载操作符与转换)

第十四章:重载操作符与转换 重载操作符必须具有至少一个类类型或枚举类型的操作数,这条规则强制重载操作符不能重新定义用于内置类型对象的操作符含义。 重载操作符时使用默认实参是非法的。 大多数重...
  • ithzhang
  • ithzhang
  • 2012年05月24日 11:05
  • 2226

C++中重载和覆盖的区别

一. 重载1.
  • cgl1079743846
  • cgl1079743846
  • 2014年05月28日 11:29
  • 7822

C++新特性(类与对象的各种指针和引用)

对象与函数的关系(知道如何把对象指针和引用作为函数参数)   将对象指针作为函数的参数,传递给函数处理有两个好处 1、减少数据分配的时间和空间,提高了程序运行的效率; 2、在被调函数中,可以直...
  • pearl333
  • pearl333
  • 2012年09月28日 10:22
  • 4101

C++类的对象和类的指针的区别、指针和引用的区别

#include #include using namespace std; class Student { public: static int number; str...
  • liulina603
  • liulina603
  • 2015年08月05日 08:44
  • 3211

C++访问控制-三种继承方式

不同继承方式的影响主要体现在: 1、派生类成员对基类成员的访问控制。 2、派生类对象对基类成员的访问控制。 三种继承方式: 1、公有继承(public) ① 基类的public和protected成员...
  • shangyaowei
  • shangyaowei
  • 2013年12月19日 20:46
  • 1822

C++定义与声明 区别

C++ 声明 定义
  • sjxbf
  • sjxbf
  • 2011年04月08日 17:13
  • 31388

C++类的访问控制

前言C++类中关于访问说明符的关键字是public,protected和private,由于C++的继承的访问说明符不同,这里会牵扯出非常多不同的情况,本文尝试对此进行整理无继承public,prot...
  • u010185700
  • u010185700
  • 2016年09月14日 16:00
  • 707

C++之类对象的返回与引用

一、类对象的返回 在拷贝构造器中提到过:class A{}; A func(A a){ return a; }int main(){ A x; func(x); }调用fun...
  • maoliran
  • maoliran
  • 2016年05月30日 11:19
  • 3214

C++中对类和对象基础理解

C++中对类和对象基础理解 C++不是纯面向对象的编程语言,而是基于面向对象的语言,因为C++中包含C语言的部分,而C语言是面向过程的。 面向对象的三大特性:封装、继承、多态。 封装:将方法和数...
  • demi_hu
  • demi_hu
  • 2017年03月04日 17:41
  • 972
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++类—重载操作符
举报原因:
原因补充:

(最多只允许输入30个字)