C++ Primer复制控制 13.2 赋值操作符

转载 2016年06月01日 19:54:13

在面向对象程序设计中,对象间的相互拷贝和赋值是经常进行的操作。

如果对象在申明的同时马上进行的初始化操作,则称之为拷贝运算。例如:

class1 A("af"); class1 B=A;     

此时其实际调用的是B(A)这样的浅拷贝操作。   

如果对象在申明之后,在进行的赋值运算,我们称之为赋值运算。例如:       

class1 A("af"); class1 B;        

B=A;        

此时实际调用的类的缺省赋值函数B.operator=(A);        

不管是浅拷贝还是赋值运算,其都有缺省的定义。也就是说,即使我们不overload这两种operation,仍然可以运行。

那么,我们到底需不需要overload这两种operation 呢?        

答案就是:一般,我们我们需要手动编写析构函数的类,都需要overload 拷贝函数和赋值运算符。

note1:
    不要按值向函数传递对象。如果对象有内部指针指向动态分配的堆内存,丝毫不要考虑把对象按值传递给函数,要按引用传递。并记住:若函数不能改变参数对象的状态和目标对象的状态,则要使用const修饰符 

note2:问题:
    对于类的成员需要动态申请堆空间的类的对象,大家都知道,我们都最好要overload其赋值函数和拷贝函数。拷贝构造函数是没有任何返回类型的,这点毋庸置疑。 而赋值函数可以返回多种类型,例如以上讲的void,类本身class1,以及类的引用 class &? 问,这几种赋值函数的返回各有什么异同?
    答:1 如果赋值函数返回的是void ,我们知道,其唯一一点需要注意的是,其不支持链式赋值运算,即a=b=c这样是不允许的!
          2对于返回的是类对象本身,还是类对象的引用,其有着本质的区别!
              第一:如果其返回的是类对象本身
   A operator =(A& a)
    {
            if(name!=NULL)
                deletename;
        
this->_id=a._id;
        int len=strlen(a.name);
       name=new char[len+1];
        strcpy(name,a.name);
        return *this;
    }
          其过程是这样的:
                       class1A("herengnag");
                        class1B;   
                        B=A;
                    看似简单的赋值操作,其所有的过程如下:
                       1 释放对象原来的堆资源
                       2 重新申请堆空间
                       3 拷贝源的值到对象的堆空间的值
                       4 创建临时对象(调用临时对象拷贝构造函数),将临时对象返回
                       
5. 临时对象结束,调用临时对象析构函数,释放临时对象堆内存
my god,还真复杂!!
            但是,在这些步骤里面,如果第4步,我们没有overload 拷贝函数,也就是没有进行深拷贝。那么在进行第5步释放临时对象的heap 空间时,将释放掉的是和目标对象同一块的heap空间。这样当目标对象B作用域结束调用析构函数时,就会产生错误!!
            因此,如果赋值运算符返回的是类对象本身,那么一定要overload 类的拷贝函数(进行深拷贝)!
            第二:如果赋值运算符返回的是对象的引用,
   A& operator =(A& a)
    {
            if(name!=NULL)
                deletename;
        
this->_id=a._id;
        
int len=strlen(a.name);
       name=new char[len+1];
        strcpy(name,a.name);
        return *this;
    }
        那么其过程如下:
                   1释放掉原来对象所占有的堆空间
                   1.申请一块新的堆内存
                   2将源对象的堆内存的值copy给新的堆内存
                   3返回源对象的引用
                    4结束。
    因此,如果赋值运算符返回的是对象引用,那么其不会调用类的拷贝构造函数,这是问题的关键所在!!

举报

相关文章推荐

C++ Primer复制控制 13.2 赋值操作符

在面向对象程序设计中,对象间的相互拷贝和赋值是经常进行的操作。 如果对象在申明的同时马上进行的初始化操作,则称之为拷贝运算。例如: class1 A("af"); class1 B=A;     ...

重温C++ primer 之复制控制(复制构造函数,赋值操作符,析构函数)

#pragma once #include #include class Exmpl { public: Exmpl(void){} Exmpl(const Exmpl &) { std::c...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

聊聊C++中复制构造函数和赋值操作符

复制构造函数:只有单个形参,而且形参是对本类类型对象的引用(常用const修饰),这样的构造函数称为复制构造函数。与默认构造函数一样,复制构造函数可由编译器隐式调用。复制构造函数可以用于: ...

C++复制构造函数与重载赋值操作符

http://www.cnblogs.com/BlueTzar/articles/1223313.html 复制构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它的唯一的一个参数是本类型的一...

C++复制构造函数和赋值操作符的区别

转自:http://blog.csdn.net/randyjiawenjie/article/details/6666937 今天做C++ primer的习题,被复制构造函数和赋值符的区别弄晕了。简...

C++语法基础--复制控制--复制构造函数 ,赋值操作符 ,析构函数

复制控制(编译器自动实现这些操作)             *复制构造函数             *赋值操作符        ...

C++中复制构造函数与重载赋值操作符总结

前言 这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 复制构造函数和重载赋值操作符的定义;复制构造函数和重载赋值操作符的调用时机;复制构造函数和重载赋值操作符的实...

复制构造函数与赋值操作符的重载

1. 试验功能:带有指针成员且指针成员为类类型时,自定义复制构造函数与赋值操作符的行为是怎样的。 2. 试验结果: (1)当指针成员为一般普通成员时,我们可以自己在复制构造函数中为指针分配内存并拷...
  • ljq32
  • ljq32
  • 2012-08-10 16:21
  • 1355

C++ Primer 学习笔记 — 复制控制

复制控制详细介绍——复制构造函数、赋值构造函数和析构函数

第13章 复制控制 (part1) 复制构造函数 & 赋值操作符 & 析构函数

每种类型,无论是内置类型还是类类型,都对该类型对象的一组(可能为空的)操作的含义进行了定义。比如,我们可以将两个 int 值相加,运行 vector 对象的 size 操作,等等。这些操作定义了用...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)