原创 赋值函数剖析

2010-7-14 11:12 1315 3 3 分类: MCU/ 嵌入式

 


作者:冯利美,华清远见嵌入式学院讲师。


构造函数,拷贝构造函数,赋值函数和析构函数是C++类中最基本的四大函数。当设计一个类时,要首先考虑这四大函数的写法。若没有提供显式的实现,编译器会产生默认的函数。若类中有指针成员,必须提供这四大函数的实现,否则容易出现内存错误。本文针对赋值函数进行了分析,包括其原型,调用场合,存在的必要性等方面。


1. 赋值函数原型


A& operator =( const A& other) { … … }


2. 调用场合


A a1(10);        // 为a1调用构造函数
        A a2;         // 为a2调用默认构造函数
        a2 = a1;        // 为a2调用赋值函数。
        A & operator =(const A &a){
                if (&a == this)
                        return *this;
                //... 具体赋值操作
                return *this;}


3.考察:


1) 为何首先检查同一性?


答:为了防止自赋值


2) (a=b)=c或者a=(b=c)是否合法


答:合法


3) 若定义为void operator =(const A &a) 有何局限?


答:没有了返回值,就不能实现a=b=c 这样的链式复值。用法不够灵活。


4) 赋值函数存在的必要性


答:以类String的两个对象a,b为例,假设a.m_data的内容为“hello”,b.m_data的内容为“world”。现将a赋给b,缺省赋值函数的“位拷贝”意味着执行b.m_data = a.m_data。这将造成三个错误:一是b.m_data原有的内存没被释放,造成内存泄露;二是b.m_data和a.m_data指向同一块内存,a或b任何一方变动都会影响另一方;三是在对象被析构时,m_data被释放了两次。


5) 若定义为A operator =(const A &a){...return *this;},有何局限?


答:若返回值改成了不是引用类型,则有两个局限。


第一:对于a=(b=c), 操作仍然可以正常进行,但效率降低了。


因为此时的赋值函数会产生一个临时对象,类似于 A tmp=*this. 假设b=c操作产生tmp1, 然后执行a=tmp1,该过程还会产生临时对象tmp2。还会有tmp1, tmp2的析构。过程变得复杂许多。


第二:对于(a=b)=c, 操作不能以期望的方式进行。


假设a=b产生临时对象tmp1, 然后tmp1=c, 这样a不能获得c的值,与常识不符。

文章评论0条评论)

登录后参与讨论
我要评论
0
3
关闭 站长推荐上一条 /2 下一条