C++重载赋值运算符

Posted LC编程开发者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++重载赋值运算符相关的知识,希望对你有一定的参考价值。

重载赋值运算符

       上面我们讨论了“对象赋值异常”的问题。当对象的成员变量是指针类型时,对象之间的赋值,应该要对指针成员变量进行特殊操作。

       要解决这个问题,需要重载赋值运算符。那么,运算符的重载在后续章节深入学习。

       在这里,我们预先学习“赋值运算符重载”的知识。是为了让知识点归纳连贯起来。让读者知道,对象的赋值存在浅拷贝的问题。需要重载赋值运算符,进行深拷贝,才可以解决问题。

       所以,我们教学的方法,不是死板地列出C++的知识点,而是针对问题,分析问题,解决问题。当学习了运算符的重载之后,再回来看该章节也行。但是,我们需要知道的一个知识点是:对象赋值存在浅拷贝问题,需要重载赋值运算符,进行深拷贝。

       下面是一个测试例子,重载了赋值运算符。

程序运行结果如下:

       可以看到,使用stud对象给stud1对象赋值,当stud对象销毁之后,stud1对象的数据还是正常。因为我们增加了“重载赋值运算符”函数的定义,在该函数中,对涉及到指针类型的成员变量,进行内存申请和数据拷贝。该函数的定义如下:

    void operator = (const student& s){

        if(NULL != name){

            delete []name; //如果name已经申请内存,先释放内存;

        }

        name = new char[32]; //申请内存

        strcpy(name, s.name); //拷贝数据

        if(NULL != addr){

            delete []addr; //如果addr已经申请内存,先释放内存;

        }

        addr = new char[32]; //申请内存

        strcpy(addr, s.addr); //拷贝数据

        number = s.number;

    }

       可以看到,给对象赋值的时候,对象的name, addr是指针类型,那么,需要申请内存再拷贝数据。而且,如果name, addr成员变量不是NULL类型,可能是已经申请了内存空间,那么,我们对内存空间进行释放,再次申请新的内存空间。保证对象的指针成员变量得到合法的内存地址。

       上面的代码,我们重载了赋值运算符,满足两个对象之间的赋值。那么,如果有如下的main()函数,会产生什么结果?

int main(void){

    student stud1, stud2;

    if(1){

        student stud("wkf", "www.mylinux.vip", 13926572996);

        stud1 = stud2 = stud;

    }

    stud1.print();

    stud2.print();

    return 0;

}

       编译异常,异常信息如下:

wkf@ubuntu:~/c++$ g++ test.cpp -o exe

test.cpp: In function ‘int main()’:

test.cpp:55: error: no match for ‘operator=’ in ‘stud1 = stud2.student::operator=(((const student&)((const student*)(& stud))))’

test.cpp:36: note: candidates are: void student::operator=(const student&)

       可以看到,执行stud1 = stud2 语句的时候,出现了错误。那么,为什么会这样?

       执行 stud2 = stud; 成功,但是,执行 stud1 = stud2 语句失败?

       这个问题,当深入学习运算符重载的时候,就可以解决。解决方法就是修改重载赋值运算符,如下:

    student& operator = (const student& s){

        if(NULL != name){

            delete []name;

        }

        name = new char[32];

        strcpy(name, s.name);

        if(NULL != addr){

            delete []addr;

        }

        addr = new char[32];

        strcpy(addr, s.addr);

        number = s.number;

        return *this;

    }

       此时,编译程序,运行OK。程序分析如下:

(1) 执行stud1 = stud2 = stud;语句,分成两个步骤,先执行 stud2 = stud; 语句,把得到的返回值再赋给stud1对象。

(2) 执行 stud2 = stud; 语句的时候,调用重载的赋值运算符,相当于:

stud2.operator = (stud);

       此时,是stud2对象调用重载的赋值运算符函数,调用完之后,返回一个student对象的引用。所以,在重载赋值运算符中,赋值完之后,返回*this对象,就是返回stud2对象。

       所以,把stud2对象返回,再赋值给stud1对象;相当于stud1 = stud2; 此时,才是正确的逻辑。

韦凯峰 Linux C/C++ 程序设计教程,Linux 系统编程,Openwrt 系统开发,微信:13926572996,QQ:1523520001,博客:www.mylinux.vip

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

以上是关于C++重载赋值运算符的主要内容,如果未能解决你的问题,请参考以下文章

C++重载赋值运算符

c++中为啥赋值运算符重载返回类型是引用

C++ ——赋值运算符重载函数

C++基础-5-运算符重载(加号,左移,递增,赋值,关系,函数调用)

c++ 拷贝构造函数与赋值运算符重载函数的区别是

c++重载赋值操作符的返回值是啥?