zoukankan      html  css  js  c++  java
  • C++中的构造函数,拷贝构造函数和赋值运算

    关于C++中的构造函数,拷贝构造函数和赋值运算,以前看过一篇《高质量C++/C编程指南》的文章中介绍的很清楚,网上能搜索到,如果想详细了解这方面的知识可以参看一下这篇文章。

    常见的给对象赋值方式有构造函数,拷贝构造函数,赋值运算符这三种方法,如下代码演示了这几种常见的方法。

        A a1;
        A a2(a1);
        A a3 = a1;
        a3 = a2;

    如果不手动写代码,C++编译器默认提供了构造函数,拷贝构造函数,赋值运算符的这三种方法的默认实现。

    默认构造函数没有参数,它什么也不做,程序员如果要实现手动构造的话则需要编写相应的重载版本。前面代码的第一行就是通过默认构造函数来创建一个对象,一般也不会和其它几种构造方式混淆,和C#,Java等其它语言也是一样的,还比较容易掌握。

    而拷贝构造函数和赋值运算符则是C++独有的,也是很多人所不熟悉的地方。构造函数和拷贝构造函数用于从一个对象复制出另一个对象。系统提供的默认拷贝构造函数和赋值运算的工作方式是内存拷贝,也就是浅拷贝。如果对象中用到了需要手动释放的对象,则会出现问题,这时就要手动重载这两个函数,实现深拷贝。

    拷贝构造函数和赋值运算的重载声明如下:

        A (const A& other)
        A& operator = (const A& other)

    要实现这两个函数,我们必须知道这几个基本信息

    1. 什么时候会调用
    2. 输入参数代表什么
    3. 函数体应该如何实现
    4. 返回值代表什么

    1. 什么时候会调用

    首先我们来看这两个函数什么时候会调用,对于上面代码的2-4行。

    • 第二行:A a2(a1);     这个很明显调用的是拷贝构造函数
    • 第四行:a3 = a2    这个很明显调用的是赋值运算
    • 第三行:A a3 = a1;    这个就没其它几个那么好懂了,看起来即像是调用拷贝构造函数创建一个对象,又像是调用赋值运算复制一个对象,还是两个都调了? 实际上,这个调用的是拷贝构造函数,和第二行的方式是等价的。

    对于第三行的 A a3 = a1; 这种方式,我们如何去理解它呢?实际上有一个很好记的统一的大原则:从无到有是调用构造函数,从有到有调用的是赋值运算。基于这个原则,前面四行代码哪个是调用哪个函数就很好区分了。

    2. 输入参数代表什么

    拷贝构造函数和赋值运算函数都一个入参,这个入参很明显是待复制的数据源对象,简单讲就是括号里面的,= 号右边的。

    从拷贝构造函数和赋值运算函数的声名形式来看,它是一个const型的,说明复制的过程中不应该修改源对象。当然,如果定义为const型的也能编过去,就是用起来没那么好用罢了(可以参看后面的effective C++ 条款15链接)。

    3. 函数体应该如何实现

    拷贝构造函数和赋值运算的功能一样,都是根据已有的对象复制出新对象。它们拥有同样的入参,实现的功能也应该是一样的。

    按照c++的设计原则,重载了一个就应该重载另一个,并且有相同的实现,否则这种不一致性很容易导致程序出问题

    至于复制过程如何实现,关于如何实现对象深拷贝的网上有许多文章详细的讲解了这一过程,这个也是c程序员的基本技能。由于篇幅所限这里就不多介绍了。我的一般方法就是:先实现位拷贝,然后在对动态申请对象编码实现深拷贝

    4. 返回值代表什么

    拷贝构造函数没有返回值,这个很好理解。但赋值运算有一个返回值就不那么容易理解了,数据复制操作时在函数运算体内就已经完成了,还要一个返回值干嘛,返回到外面有什么用?

    最初我也认为这个函数返回值设计为void型更容易理解,后来才知道返回值主要是为了实现类似w = x = y = z = 0的连等,不过连等这个编程习惯本身就不大好。

    最后再看看应该如何返回,其实直接返回个return *this; 就可以了,至于为什么不用其它的方式,还是看看权威的解释吧(链接失效的话直接google搜索标题):effective C++ 条款15: 让operator=返回*this的引用

  • 相关阅读:
    在JAVA应用中远程提交MapReduce程序至Hadoop集群运行
    ImpalaJDBCDriver 500051
    在Linux上安装Python3
    MySQL导入之mysqlimport
    hadoop mapreduce的本地模式及yarn模式
    MySQL之mysqldump的使用
    MapReduce的本地运行模式(debug调试)
    09 MySQL触发器
    P3168 [CQOI2015]任务查询系统
    P4124[CQOI]手机号码
  • 原文地址:https://www.cnblogs.com/TianFang/p/2742121.html
Copyright © 2011-2022 走看看