《挑战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++类静态数据成员与类静态成员函数 在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? ...
随机推荐
- C# ——Parallel类
一.Parallel类 Parallel类提供了数据和任务的并行性: 二.Paraller.For() Paraller.For()方法类似于C#的for循环语句,也是多次执行一个任务.使用Paral ...
- ASP.NET面试题130道
130道ASP.NET面试题 1. 简述 private. protected. public. internal 修饰符的访问权限. 答 . private : 私有成员, 在类的内部才可以访问. ...
- web API .net - .net core 对比学习-依赖注入
今天我们来看一下 .net web api 和 .net core web api依赖注入机制的差异. 首先我们分别在.net web api 和 .net core web api新建文件夹Serv ...
- 关闭 禁止 window10 UpdateOrchestrator UsoSvc服务
背景故事:w10流氓更新关了! 然后重启还更新? 读者肯定关过win10自动跟新服务 如图: 然后 还有这个流氓设置 然而微软还有一招啊! 前有win10 update 后有计划任务 powershe ...
- 常用的MySQL命令
1.新建数据库: create database person; 2.使用数据库 use person: 3.创建一个表格 create table student ( id int(10) not ...
- Keepalived简单理解
Keepalived Keepalived是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障.一个LVS服务会有2台服务器运行Keepalived,一台为主服务器(MASTE ...
- springboot+security整合(1)
说明 springboot 版本 2.0.3源码地址:点击跳转 系列 springboot+security 整合(1) springboot+security 整合(2) springboot+se ...
- 过滤器实现Token验证(登录验证+过期验证)---简单的实现
功能:登录验证+过期验证+注销清除cookie+未注销下关闭或刷新浏览器仍可直接访问action概述:token只存在客户端cookie,后端AES加密+解密+验证,每一次成功访问action都会刷新 ...
- (备忘)解决用Xftp向CentOS7 传文件速度慢的问题
问题原因:之前用XFTP上传文件的时候一直挺好的,今天突然速度特别慢,上传了一个多小时也没把一个一百兆的文件成功上传 查询过程: 1.网络原因:网络的确有点卡,但不至于这么慢吧,几K的速度,鉴于网络问 ...
- Kubernetes-Istio之Gateway和VirtualService
1: 确定入口IP和端口 执行以下命令以确定Kubernetes集群是否在支持外部负载均衡器的环境中运行: kubectl get svc istio-ingressgateway -n istio- ...