关于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的引用

C++中的构造函数,拷贝构造函数和赋值运算的更多相关文章

  1. 关于C++ 中 thread 的拷贝构造函数

    起因来自于<C++并发编程实战>的这样一个例子 #include <thread> #include <iostream> #include <stdexce ...

  2. C++构造函数 & 拷贝构造函数 & 派生类的构造函数 & 虚继承的构造函数

    构造函数 ,是一种特殊的方法 .主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 .特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数 ...

  3. C++中构造函数,拷贝构造函数和赋值函数的区别和实现

    C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法.下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类成员函数,是当创建一个类的对象 ...

  4. C++中的构造函数,拷贝构造函数,赋值函数

    C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法.下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类成员函数,是当创建一个类的对象 ...

  5. 【C++】拷贝构造函数和赋值符函数

    在C++中,调用拷贝构造函数有三种情况: 1.一个对象作为函数参数,以值传递的方式传入函数体. 2.一个对象作为函数返回值,以值传递的方式从函数返回. 3.一个对象用于给另外一个对象进行初始化(复制初 ...

  6. C++中的拷贝构造函数

    一.拷贝构造函数: 格式: A(const  A& a);  总结: 系统为对象B分配了内存并完成了与对象testA的复制过程,就类对象而言,相同类型的类对象是通过拷贝构造函数来完成整个复制过 ...

  7. 【转】C++的拷贝构造函数深度解读,值得一看

    建议看原帖  地址:http://blog.csdn.net/lwbeyond/article/details/6202256 一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很 ...

  8. C++拷贝构造函数详解(转载)

    一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a = 100; int b = a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员 ...

  9. 【转】 c++拷贝构造函数(深拷贝,浅拷贝)详解

     c++拷贝构造函数(深拷贝,浅拷贝)详解 2013-11-05 20:30:29 分类: C/C++ 原文地址:http://blog.chinaunix.net/uid-28977986-id-3 ...

  10. [016]转--C++拷贝构造函数详解

    一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a = 100; int b = a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员 ...

随机推荐

  1. OC12_自动释放池

    // // Dog.h // OC12_自动释放池 // // Created by zhangxueming on 15/6/18. // Copyright (c) 2015年 zhangxuem ...

  2. [译]JavaScript检测浏览器前缀

    原文地址: Detect Vendor Prefix with JavaScript 不管浏览器私有前缀的现状如何,我们还是要与之为伴,并且有时候还需要利用它来做一些事情.这些前缀可以用于CSS(比如 ...

  3. tip 2:找最小公倍数之Boost

    今天在codewars上面做了一题,kata5的,其中一个实现函数是几个数字的最小公倍数.自己的代码编译虽然也成功了,但是不够简介.看了别人的代码才发现可以直接调用Boost的math模块. 看eff ...

  4. xamarin.ios 豆瓣电台视频教程

    视频中提到的网址: http://www.sufeinet.com/thread-655-1-1.html https://github.com/akfish/fm-terminal/blob/dev ...

  5. python练习 根据日志中的ip和url排序

    #!/usr/bin/env python #coding:utf-8 def open_file(file_name): res={} with open(file_name) as f: for ...

  6. bind()实现

    bind()函数是在 ECMA-262 第五版才被加入:它可能无法在所有浏览器上运行.这就需要我们自己实现bind()函数了 简单实现bind()方法: Function.prototype.bind ...

  7. NPOI Excel导入 导出

    添加引用 using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using System; using System.Collections.Gene ...

  8. 纯CSS3代码实现简单的图片轮播

    以4张图片为例:1.基本布局:将4张图片左浮动横向并排放入一个div容器内,图片设置统一尺寸,div宽度设置4个图片的总尺寸,然后放入相框容器div,相框设置1个图片的大小并设置溢出隐藏,以保证正确显 ...

  9. sersync 实时同步工具

    出处:http://code.google.com/p/sersync/ 当前版本的sersync依赖于rsync进行同步.如下图所示,在同步主服务器上开启sersync,将监控路径中的文件同步到目标 ...

  10. 详解AngularJS中的filter过滤器用法

    系统的学习了一下angularjs,发现angularjs的有些思想根php的模块smarty很像,例如数据绑定,filter.如果对smarty比较熟悉的话,学习angularjs会比较容易一点.这 ...