赋值函数剖析

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

构造函数,拷贝构造函数,赋值函数和析构函数是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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值