《挑战30天C++入门极限》C++运算符重载转换运算符
|
C++运算符重载转换运算符 为什么需要转换运算符? 大家知道对于内置类型的数据我们可以通过强制转换符的使用来转换数据,例如(int)2.1f;自定义类也是类型,那么自定义类的对象在很多情况下也需要支持此操作,C++提供了转换运算符重载函数,它使得自定义类对象的强转换成为可能。 转换运算符的生命方式比较特别,方法如下: operator 类名(); 转换运算符的重载函数是没有返回类型的,它和类的构造函数,析构函数一样是不遵循函数有返回类型的规定的,他们都没有返回值。 下面我看一个例子,看看它是如何工作的: //例1 在例子中我们利用转换运算符将Test类的对象强转换成了int类型并输出,注意观察转换运算符函数的运行状态,发现并没有产生临时对象,证明了它与普通函数并不相同,虽然它带有return语句。 在很多情况下,类的强转换运算符还可以作为类对象加运算重载函数使用,尽管他们的意义并不相同,下面的例子,就是利用转换运算符,将两个类对象转换成int后,相加并创建临时类对象,后再赋给另一个对象。 代码如下: //例2 代码中的c=a+b;属于隐式转换,它的实现过程与c=Test((int)a+(int)b);完全相同。 运行结果如下图示(注意观察内存地址,观察构造与析构过程,执行过程图中有解释): 当一个类含有转换运算符重载函数的时候,有时候会破坏C++原有规则,导致运算效率降低,这一点不得不注意。 示例如下: //例3 按照C++对无名对象的约定,Test b=Test(99);C++是会按照Test 运行结果如下图所示(运行过程的解释见图): 由于类的转换运算符与类的运算符重载函数,在某些地方上使用的时候,有功能相似的地方,如果两者都存在于类中,那么虽然运行结果正确,但其运行过程会出现一些意向不到的步骤,导致程序运行效率降低。 下面的例子就是这个情况,代码如下: //例4 运行过程见下图。 从图中我们可以清晰的看到,不必要的运算过程被执行,导致开销增大,读者在理解此例的时候要格外小心! 现在总结一下转换运算符的优点与缺点: 优点:在不提供带有类对象参数的运算符重载函数的情况下,转换运算符重载函数可以将类对象转换成需要的类型,然后进行运算,最后在构造成类对象,这一点和类的运算符重载函数有相同的功效。(例2就是这种情况) 缺点:如果一个类只有转换运算符重载函数,而没有真正意义上运算符重载函数,当用转换运算符重载函数替代运算符重载函数,进行工作的时候,就会让程序的可读性降低,歪曲了运算符操作的真正含义。(例2中的c=a+b;//隐式转换,就是例子,事实上a+b的作用只是对返回的整型数据进行了加运算,而对象赋值的操作是系统隐式的帮大家转换成了c=Test(a+b)。) 最后我们来说一下,多路径转换的多义性问题,多义性问题一直是C++编程中容易忽视的问题,但它的确是不容小视,当问题隐藏起来的时候你不会发觉,一旦触发麻烦就来了。 类的转换构造函数与类的转换运算符重载函数是互逆的。(例3中的Test(int a = 但是当他们是出现在两个不同的类中,对于一个类对象转换来说,同时拥有两种近似的转换途径的时候,多义性的问题就暴露出来,导致编译出错。 下例就是这个状态: //程序作者:管宁 代码中的A at=A(bt);运行正常,因为系统发现对象at还未构造,所以优先选取了A类的转换构造函数处理了,没有产生二义性问题。 但是代码中的tp(bt);编译错误,这是因为函数tp的参数要求的是一个A类对象,而我们给他的则是一个B类对象,而在A类与B类中都有一个类似的操作,可以将B类对象转换成A类对象,系统不知道是选取A类的转换构造函数进行构造处理,还是选择B类中的转换运算符号重载函数处理,系统拒绝从他们两个中选一个,所以编译错误。 我们修改tp(bt)为tp(A::A(bt));编译正常,因为我们显式的明确的告诉系统应该使用A类的转换构造函数处理,所以,显式的告诉计算机应该如何处理数据,通常可以解决多义性问题。 |
|||
《挑战30天C++入门极限》C++运算符重载转换运算符的更多相关文章
- 《挑战30天C++入门极限》C++运算符重载赋值运算符
C++运算符重载赋值运算符 自定义类的赋值运算符重载函数的作用与内置赋值运算符的作用类似,但是要要注意的是,它与拷贝构造函数与析构函数一样,要注意深拷贝浅拷贝的问题,在没有深拷贝浅拷贝的情况下 ...
- 《挑战30天C++入门极限》对C++递增(增量)运算符重载的思考
对C++递增(增量)运算符重载的思考 在前面的章节中我们已经接触过递增运算符的重载,那时候我们并没有区分前递增与后递增的差别,在通常情况下我们是分别不出++a与a++的差别的,但的确他们直接是 ...
- 《挑战30天C++入门极限》C++中利用构造函数与无名对象简化运算符重载函数
C++中利用构造函数与无名对象简化运算符重载函数 在完整描述思想之前,我们先看一下如下的例子,这个例子中的加运算符重载是以非成员函数的方式出现的: //程序作者:管宁 //站点:www.cn ...
- 《挑战30天C++入门极限》C++运算符重载函数基础及其值返回状态
C++运算符重载函数基础及其值返回状态 运算符重载是C++的重要组成部分,它可以让程序更加的简单易懂,简单的运算符使用可以使复杂函数的理解更直观. 对于普通对象来说我们很自然的会频繁使用算数运 ...
- 《挑战30天C++入门极限》C++的iostream标准库介绍(3)
C++的iostream标准库介绍(3) C语言提供了格式化输入输出的方法,C++也同样,但是C++的控制符使用起来更为简单方便,在c++下有两中方法控制格式化输入输出. 1.有流对象的成员函 ...
- 《挑战30天C++入门极限》C++的iostream标准库介绍(1)
C++的iostream标准库介绍(1) 我们从一开始就一直在利用C++的输入输出在做着各种练习,输入输出是由iostream库提供的,所以讨论此标准库是有必要的,它与C语言的stdio库不同 ...
- 《挑战30天C++入门极限》C++面向对象编程入门:构造函数与析构函数
C++面向对象编程入门:构造函数与析构函数 请注意,这一节内容是c++的重点,要特别注意! 我们先说一下什么是构造函数. 上一个教程我们简单说了关于类的一些基本内容,对于类对象成员的初始化我们 ...
- 《挑战30天C++入门极限》入门教程:实例详解C++友元
入门教程:实例详解C++友元 在说明什么是友元之前,我们先说明一下为什么需要友元与友元的缺点: 通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都生命成为pu ...
- 《挑战30天C++入门极限》C++类静态数据成员与类静态成员函数
C++类静态数据成员与类静态成员函数 在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? ...
随机推荐
- screen命令下,自启动设置
建立autostart.sh文件 #!/bin/bash screen_name=$"coffeetest:9100" screen -dmS $screen_name cmd=$ ...
- R_基本统计分析_06
summary()提供基础的统计信息 sapply(x,FUN,options)可以指定统计函数 fivenum()可以返回图基五数 Hmisc 中的describe(data)返回变量,观测的变量, ...
- JS权威指南读书笔记(七)
第十七章 事件处理 1 客户端JS程序采用了异步事件驱动编程模型. 2 关于事件的重要定义 a 事件类型(event type) b 事件目标(event target) target ...
- requests模块 简单使用
目录 requests模块 简单使用 Anaconda简单了解 简单了解 requests模块 使用requests模块 爬取搜狗首页源码数据 实现一个简易的网页采集器 解决乱码问题 解决UA检测问题 ...
- 实战OpenGLES--iOS平台使用OpenGLES渲染YUV图片
上一篇文章 实战FFmpeg--iOS平台使用FFmpeg将视频文件转换为YUV文件 演示了如何将视频文件转换为yuv文件保存,现在要做的是如何将yuv文件利用OpenGLES渲染展示出图像画面.要将 ...
- js中的call()、apply()、bind()
js中的一个核心概念就是对this的理解,关于this前面也有说过,不过在有些情况下,还是需要手动去改变this的指向,这里总结一下,js中关于this操作的三种方法 call() apply() b ...
- linux基础命令之1
1.创建文件夹:mkdir 文件夹名称 2.创建文件:touch 文件名称 3.编辑文件:vi 文件名称 4.保存文件::wq
- 【JUC】4.Synchronized与ReentrantLock对比
与synchronized相同,ReentrantLock也是一种互斥锁: synchronized与ReentrantLock的对比: 都是可重入锁 可以再次获取自己的内部锁,即:一个线程获取某对象 ...
- yarn 错误There appears to be trouble with your network connection. Retrying...
原因:yarn超时 解决途径:1.安装好后更换淘宝镜像 yarn config set registry https://registry.npm.taobao.org
- 开发一个代码的自动生成器,使用Jfinal4.3+Swagger+Sql
-- 所有表名select column_name 列名, data_type 字段类型, column_comment 字段注释 from information_schema.columns ...