第十五章、重载运算与类型转换

一、基本概念

1、重载运算符是具有特殊名字的函数:由关键字operator和其他要定义的运算符号共同组成

2、重载运算符的参数数量与该运算符作用的运算对象一样多

  • 当一个重载的运算符是成员函数时,this会绑定到左侧运算对象,成员运算符函数的显示参数数量比运算对象的数量少一个

3、对于一个运算符函数,它要么是类的成员,或者至少含有一个类类型的参数

  • 当作用符作用于内置类型的运算对象时,无法改变该运算符的含义

例:

//非成员运算符函数的等价调用
data1 + data2;        //普通的表达式
operator+(data1, data2);    //等价的函数调用
//operator运算符是成员函数
data1 += data2;        //基于调用的表达式
data1.operator += (data2);    //等价的调用

4、通常情况下,不应该重载:逗号、取地址、逻辑与、逻辑或运算符

5、当设计一个类时,首先应该考虑的是这个类提供哪些操作;如果某些操作在逻辑上与运算符相关,则他们适合定义成重载的运算符

  • 如果类定义了operator==;通常也应该定义operator!=

    • 相等运算符合不相等运算符中的一个应该把工作委托给另一个
  • 赋值运算符和复合赋值运算应该返回左侧运算符的一个引用

6、只有当操作的含义对于用于来说清晰明了是才运用运算符

7、定义成成员函数还是非成员函数的准则:

  • 赋值(=)、下标([ ])、调用(())和成员访问箭头(->)运算符必须是成员

  • 复合赋值运算符一般来说应该是成员
  • 改变对象状态的运算符或者与给定类型密切相关的运算符,如递增、递减和解引用运算符,通常应该是成员
  • 具有对称性的运算符可能转换任意一端的运算对象,例如算术、相等性、关系和为运算符等,通常应该是普通的非成员函数

二、输入和输出运算符

1、operator<<一般返回它的ostream形参

2、令输出运算符尽量减少格式化操作可以使用户有权控制输出的细节

3、如果希望为类自定义IO运算符,则必须将其定义成非成员函数,可以设置IO运算符声明为友元

  • 因为如果是成员函数,则会默认第一个参数绑定在了左侧对象上

4、operator>>通常返回某个给定流的引用

  • 输入运算符必须处理输入可能失败的情况,而输出运算符不许需要

    • 当流含有错误类型的数据时读取会错误

    • 当读取操作达到文件末尾或者遇到输入流的其他错误时也会失败
  • 当读取操作发生错误时,输入运算符应该负责从错误中恢复

三、算术和关系运算符

1、如果同时定义了算符运算符(+)和相关的复合赋值运算符(+=),则通常情况下应该使用复合赋值来实现算术运算符

2、如果存在唯一一种逻辑可靠的<定义,则应该考虑为这个类定义<运算符。如果类同时包含==,则当且仅当<的定义和==产生的结果一致时才定义<运算符

  • 因为有可能,一个类里面有很多种类的数据;不可以单纯的判断哪个大哪个小

四、赋值运算符

1、除了前面的赋值和移动赋值运算符,可以把一个类的对象赋值该类的另一个对象;还可以定义其他赋值运算符以使用别的类型作为右侧运算对象:如花括号的列表元素

2、和拷贝赋值和移动赋值一样,其他重载的赋值运算符也必须先释放当前内存空间,再创建一个新空间

3、赋值运算符必须定义成类的成员;复合赋值运算符通常也应该是类的成员;这两类运算符都应该返回左侧运算对象的引用

五、下标运算符

1、下标运算符通常以所访问元素的引用作为返回值

2、我们最好同时定义下标运算符的常量版本和非常量版本;一个返回普通引用,另一个是类的常量成员并且返回常量引用

六、递增和递减运算符

1、定义递增和递减运算符的类应该同时定义前置版本和后置版本。这些运算符都应该被定义成类的成员

2、前置运算符应该返回递增或者递减后对象的引用

3、后置版本接收一个额外的(不被使用)的int类型的形参

  • 后置运算符应该返回对象的原值,返回的形式是一个值而非引用

    StrBlobPtr StrBlobPtr::operator++(int)
    {
        StrBlobPtr ret = *this;//提前把*this即原值保存了下来
        ++*this;              //这里使用了前置版本++运算符
        return ret;        //注意这里返回的是ret
    }
  • 后置运算符调用各自的前置版本来完成实际工作

4、如果我们想通过函数调用的方式调用后置版本,则必须为它的整型参数传递一个值,尽管这个值不被使用

    StrBlobPtr p(a1);
    p.operator++(0);

七、成员访问运算符

1、箭头运算符必须是类的成员。解引用通常也是,但不是必须

2、operator*可以完成任何我们所指定的操作,比如打印值;而箭头运算符不是,只能获得成员

  • 重载的箭头运算符必须返回类的指针或者自定义了箭头运算符的某个类的对象

八、函数调用运算符

1、函数调用运算符必须是一个成员函数,一个类可以定义多个不同版本的调用运算符,相互之间应该在参数数量或类型上有所区别

2、函数对象常作为泛型算法的实参

3、标准库functional头文件中定义了一组算术运算符、关系运算符和逻辑运算符的类,每个类定义了一个执行命名操作的调用的运算符

  • 标准库规定其函数对象对于指针同样适用

4、可调用对象与function

  • 可调用对象:函数、函数指针、lambda表达式、bind创建的对象、以及重载了函数调用运算符的类
  • 两个不同类型的可调用对象可能共享一个调用形式:调用形式指明了调用返回的类型以及传递给调用的实参类型

八、重载、类型转换与运算符

1、转换构造函数和类型转换运算符共同定义了类类型转换

2、类型转换运算符:operator type() const;

  • 类型转换运算符可以面向任意类型进行定义,只要该类型能作为函数的返回类型
  • 不允许转换成数组或函数类型,但允许转换成指针或引用类型
  • 类型转换运算符既没有显式的返回类型,也没有形参,而且必须定义成类的成员函数,
  • 类型转换运算符通常不应该改变待转换对象的内容,因此类型转换运算符一般定义成const成员

3、除了显式地向bool类型的转换外,应该尽量避免类型转换函数并尽可能限制那些“显然正确”的非显示构造函数

4、如果我们对同一个类既提供了转换目标是算术类型的类型转换,也提供了重载的运算符,则会遇到重载运算符与内置运算符的二义性问题

时间: 2024-10-25 12:07:03

第十五章、重载运算与类型转换的相关文章

深入浅出Zabbix 3.0 -- 第十五章 Zabbix 协议与API

今天是六.一儿童节,祝小朋友们节日快乐!发完此文就带我家小朋友出去玩耍了. 第十五章 Zabbix 协议与API 本章将介绍和开发相关的Zabbix协议和API的内容,通过对Zabbix协议和API的深入了解,你可以利用Zabbix协议编写客户端程序并将其嵌入的产品或系统中,并将数据发送到Zabbix server,这在无法安装Zabbixagent等程序的场景(例如专用的嵌入式系统)中非常有用.你也可以利用Zabbix API开发自己的业务系统,或灵活的与现有系统整合集成. 15.1 Zabb

第十五章 文件属性类的实现

                  第十五章    文件属性类的实现        根用户的权限也不能是无限大.必须考虑到保护用户的隐私!用户的文件内容.程序代码可设置为根用户也不能观看,只能是文件拥有者可以查看.修改.但根用户可以删除一切非根用户的文件.也可以查看用户的目录.所以,i_mode字符更改如下:      BU16 i_mode; // 描述文件的访问权限:文件的读.写.执行权限  // i_mode.15-13  ftype; 文件类型: 0-符号软连接文件, // 1-硬连接文

java(第十五章)

第十五章 一.字符串类String 1.String是一个类,位于java.lang包中 2.创建一个字符串对象的2种方式: String 变量名="值"; String 对象名=new String("值"); 3.字符串的常用方法 3.1 字符串长度--length() 3.2 判断值是否相等 equals() 3.3 判断字符串对象地址是否相同 == 3.4 忽略 大小写 判断 equalsIgnoreCase() 3.5 大小写转换 toLowerCase(

Java(第十五章)

第十五章 一.字符串类String 1.String是一个类,位于java.lang包中 2.创建一个字符串对象的2种方式: String 变量名="值"; String 对象名=new String("值"); 3.字符串的常用方法 3.1 字符串长度--length() 3.2 判断值是否相等 equals() 3.3 判断字符串对象地址是否相同 == 3.4 忽略 大小写 判断 equalsIgnoreCase() 3.5 大小写转换 toLowerCase(

算法导论第十五章动态规划

概述: 1.动态规划是通过组合子问题的解而解决原问题的. 2.动态规划适用于子问题不是独立的情况,也就是各子问题的包含公共的子子问题. 3.动态规划对每个子问题只求解一次,将其结果保存在一张表中. 4.动态规划的设计步骤:a.描述最优解的结构b.递归定义最优解的值c.按自底向上的方式计算最优觖的值d.由计算出的结构构造一个最优解 15.1钢条切割 钢条切割问题:给定定长的钢条和价格表,求切割方案,使得收益最大.如果n英寸的钢条的价格足够大,则不需要切割. 代码如下: //朴素递归求解钢条切割收益

C和指针 (pointers on C)——第十五章:输入输出函数

第十五章 输入输出函数 这一章读完的第一感觉就是"呵呵". 如果说上过C语言课,基本上scanf()/printf()算是用的比较熟练了.尤其是那些抽象的格式说明.还有scanf()为什么要加括号. 读过本书前面的内容的话,getchar(),putchar(),gets(),puts()这些应该也问题不大. 再如果的话,你学过计算机图形学,你玩过OpenGL,听说过双缓存机制,那么fflush()也肯定弄明白了. 再加上FILE的操作,输入输出定位刷新删除改名,流的概念. 这一章就会

第十五章 链表

/** 数组与链表的区别:数组易随机访问,链表易插入和删除 链表组成:储存数据元素的数据域,储存下一结点地址的指针域 链表易于插入与删除 lists 的用法????????????????????? *///建立一个图书链表 #include<iostream> #include <string> using namespace std; struct book //第一步: 用于建立节点. class 默认为私有 struct 默认为公有 //节点组成:①数据域 ②指针域(*ne

CSS3秘笈复习:十三章&amp;十四章&amp;十五章&amp;十六章&amp;十七章

第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮动元素.关键字:left.right或both. (2).浮动外围元素:让包含浮动元素的<div>也浮动.选择这种方法一定要在浮动容器后面的任何元素中添加一个clear属性,确保浮动元素落到容器的下方. (3).利用overflow : hidden.另一种常见的方法是在外围的样式中添加以下属性:

第十五章 文正学院成绩录入系统

这是13年上半年给文正学院做的一个成绩录入系统,只需要实现成绩录入的功能,嫁接到文正教务系统中.实现的功能如图所示. 王川 2014/5/30 第十五章 文正学院成绩录入系统,布布扣,bubuko.com

C++ Primer Plus学习:第十五章

第十五章 友元.异常和其他 友元 友元类 表 0-1 class Tv { public: friend class Remote; } Remote类可以使用Tv的数据成员,Remote类在Tv类后定义 . 友元成员函数 表 0-2 class Tv; //前向声明 class Remote { public: void chanup(Tv &t); } class Tv { public: friend void Remote::set_chan(Tv& t, int c); } 异常