重载赋值运算符怎么使用的

    我在上一篇《一个月看了两本基础书 》中提到了重载赋值运算符的一系列问题,这也是困扰我这两天的主要问题。为此,我查找了一些资料,现在整理一下,并加上我自己的一些理解。中心思想是:有了不懂的问题,可以先放一放,继续看书。而那个不懂的问题会在后面某点忽然就被你解决了。


    首先,我们来看一看《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绑定到指向左操作数的指针。”那就是说,赋值操作符也可以有两个形参了?这样说对吗?为什么?


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值