重载赋值运算符怎么使用的
2012-10-15 14:21
260 查看
我在上一篇《一个月看了两本基础书
》中提到了重载赋值运算符的一系列问题,这也是困扰我这两天的主要问题。为此,我查找了一些资料,现在整理一下,并加上我自己的一些理解。中心思想是:有了不懂的问题,可以先放一放,继续看书。而那个不懂的问题会在后面某点忽然就被你解决了。
首先,我们来看一看《C++ Primer》中对于操作符重载怎么说明的(P430):“通过操作符重载,程序员能够针对类类型的操作数定义不同的操作符版本。”这句话对于我这个菜鸟来说,真是晦涩难懂:什么叫定义不同的操作符版本? “+” 号在使用时不就一直是 “+” 号吗?它难道会变成“*”号或者“-”号?
再继续向下看:“Sales_item operator+ (const Sales_item&, const Sales_item&); //声明了加好操作符,可用于将两个Sales_item对象“相加”并获得一个Sales_item对象的副本。这句我就更不明白了:他俩本来就可以直接用“+”号相加啊,为啥还要多出来operator+呢?
不管上面的这些疑问,我们继续往下看(P432):“cout << item1 + item2 <<endl;”“cout << operator+ ( item1, item2 ) << endl;”“这两个表达式等效。”好吧,这个例子对上面的问题不但没解决,却更支持我的疑问了:可以直接“+”号啊,何必多此一举?
问题到了这里的时候,我应该继续往下看的,但是前面这么多例子支持我的疑问,我就自己在那转圈圈了:
问:“重载操作符和原来的操作符是等效的——这句话对不对?”
答:应该是对的吧……
问:“怎么证明?”
答:我不知道。
问:“怎么办?”
答:休息下吧,前面都想了那么多了,等有空再想。
而等我下次再来看的时候,我又从头把问题问了一遍,使自己陷入了无穷递归中了。
今天,我不管前面的问题了,继续向下看《数据结构》:“//长方形拷贝初始化构造函数”。去《C++ Primer》书上找复制构造函数部分时,P411这样说:“重载操作符是一些函数。”
“符号是函数?!”这样的话,重载操作符就不与普通操作符等效,因为两个操作符的定义就不同了。那继续证明,他们怎么不等效的。P434这样说:“大多数(普通)操作符对类对象没有意义。除非提供了重载定义,赋值、取地址和逗号操作符对于类类型操作数没有意义。”
下面贴段代码来说明下(转自百度知道):
好吧,现在,我们将这个运算符重载这个问题算是解决了。但是又有个新问题(P411):“赋值操作符接受单个形参。”书中解释为:“因为赋值必须是类的成员,所以this绑定到指向左操作数的指针。”那就是说,赋值操作符也可以有两个形参了?这样说对吗?为什么?
》中提到了重载赋值运算符的一系列问题,这也是困扰我这两天的主要问题。为此,我查找了一些资料,现在整理一下,并加上我自己的一些理解。中心思想是:有了不懂的问题,可以先放一放,继续看书。而那个不懂的问题会在后面某点忽然就被你解决了。
首先,我们来看一看《C++ Primer》中对于操作符重载怎么说明的(P430):“通过操作符重载,程序员能够针对类类型的操作数定义不同的操作符版本。”这句话对于我这个菜鸟来说,真是晦涩难懂:什么叫定义不同的操作符版本? “+” 号在使用时不就一直是 “+” 号吗?它难道会变成“*”号或者“-”号?
再继续向下看:“Sales_item operator+ (const Sales_item&, const Sales_item&); //声明了加好操作符,可用于将两个Sales_item对象“相加”并获得一个Sales_item对象的副本。这句我就更不明白了:他俩本来就可以直接用“+”号相加啊,为啥还要多出来operator+呢?
不管上面的这些疑问,我们继续往下看(P432):“cout << item1 + item2 <<endl;”“cout << operator+ ( item1, item2 ) << endl;”“这两个表达式等效。”好吧,这个例子对上面的问题不但没解决,却更支持我的疑问了:可以直接“+”号啊,何必多此一举?
问题到了这里的时候,我应该继续往下看的,但是前面这么多例子支持我的疑问,我就自己在那转圈圈了:
问:“重载操作符和原来的操作符是等效的——这句话对不对?”
答:应该是对的吧……
问:“怎么证明?”
答:我不知道。
问:“怎么办?”
答:休息下吧,前面都想了那么多了,等有空再想。
而等我下次再来看的时候,我又从头把问题问了一遍,使自己陷入了无穷递归中了。
今天,我不管前面的问题了,继续向下看《数据结构》:“//长方形拷贝初始化构造函数”。去《C++ Primer》书上找复制构造函数部分时,P411这样说:“重载操作符是一些函数。”
“符号是函数?!”这样的话,重载操作符就不与普通操作符等效,因为两个操作符的定义就不同了。那继续证明,他们怎么不等效的。P434这样说:“大多数(普通)操作符对类对象没有意义。除非提供了重载定义,赋值、取地址和逗号操作符对于类类型操作数没有意义。”
下面贴段代码来说明下(转自百度知道):
C++ 代码 //程序作者:管宁 //站点:www.cndev-lab.com //所有稿件均有版权,如要转载,请务必著名出处和作者 #include <iostream> using namespace std; class Internet { public: Internet(char *name,char *url) { Internet::name = new char[strlen(name)+1]; Internet::url = new char[strlen(url)+1]; if(name) { strcpy(Internet::name,name); } if(url) { strcpy(Internet::url,url); } } Internet(Internet &temp) { Internet::name=new char[strlen(temp.name)+1]; Internet::url=new char[strlen(temp.url)+1]; if(name) { strcpy(Internet::name,temp.name); } if(url) { strcpy(Internet::url,temp.url); } } ~Internet() { delete[] name; delete[] url; } Internet& operator =(Internet &temp)//赋值运算符重载函数 { delete[] this->name; delete[] this->url; this->name = new char[strlen(temp.name)+1]; this->url = new char[strlen(temp.url)+1]; if(this->name) { strcpy(this->name,temp.name); } if(this->url) { strcpy(this->url,temp.url); } return *this; } public: char *name; char *url; }; int main() { Internet a("中国软件开发实验室","www.cndev-lab.com"); Internet b = a;//b对象还不存在,所以调用拷贝构造函数,进行构造处理。 cout<<b.name<<endl<<b.url<<endl; Internet c("美国在线","www.aol.com"); b = c;//b对象已经存在,所以系统选择赋值运算符重载函数处理。 cout<<b.name<<endl<<b.url<<endl; system("pause"); } 上例代码中的Internet& operator =(Internet &temp)就是赋值运算符重载函数的定义,内部需要先delete的指针就是涉及深拷贝问题的地方,由于b对象已经构造过,name和url指针的范围已经确定,所以在复制新内容进去之前必须把堆区清除,区域的过大和过小都不好,所以跟在后面重新分配堆区大小,而后进行复制工作。 在类对象还未存在的情况下,赋值过程是通过拷贝构造函数进行构造处理(代码中的Internet b = a;就是这种情况),但当对象已经存在,那么赋值过程就是通过赋值运算符重载函数处理(例子中的b = c;就属于此种情况)。
好吧,现在,我们将这个运算符重载这个问题算是解决了。但是又有个新问题(P411):“赋值操作符接受单个形参。”书中解释为:“因为赋值必须是类的成员,所以this绑定到指向左操作数的指针。”那就是说,赋值操作符也可以有两个形参了?这样说对吗?为什么?
相关文章推荐
- 使用Cxf发布Webservice服务,如果待发布的接口中有重载方法,怎么处理??[转]
- 使用Cxf发布Webservice服务,如果待发布的接口中有重载方法,怎么处理??
- 个人怎么申请微信公众号-微信公众号使用教程33
- QT编程ARM下摄像头无法使用怎么办
- 怎么使用jquery阻止页面的离开或卸载
- oracle数据库怎么使用索引?
- Ext JS百强应用:ComboBox是什么?怎么使用?--第2强
- XMind6大纲视图要怎么使用
- 在头文件中定义变量以及static变量意味着什么?全局变量要如何正确使用?关键字extern要怎么用?
- 使用git pull文件时和本地文件冲突怎么办?
- Response.AddHeader使用实例收集 如何做下载,下载中文显示乱码怎么办 ContentType类型大全
- js里面的for in 怎么使用.md
- linux中在使用slickedit时怎么修改工程类型,比如将.exe修改成.a库
- 怎么在linux下修改IP地址?linux下使用命令轻松修改ip地址方法
- 怎么使用PHPMailer实现邮件的发送??
- CSS里面的behavior属性的作用是什么,怎么使用
- java中collection是什么?怎么理解?怎么使用?
- 怎么有效的使用Vista防火墙
- 使用JSTL在页面前的空行怎么去除?
- 使用caj文件转换器怎么转换成word文档