C++ 复制控制之复制构造函数
7月26日更新:
过了这么长的时间回过头来看,发现文章中有几个点说错(用红字标出):
- 构造函数不是只有唯一一个参数,它也可以是多参数形式,其第二参数及后继以一个默认值供应。
- 不是没有声明复制控制函数时编译器就一定会帮类声明,需要满足一定的条件。
《《=========================================================================》》
C++类用三个特殊的成员函数:复制构造函数、赋值操作符和析构函数 来决定类对象之间的初始化或赋值时发生什么。所谓的“复制控制”即通过这三个成员函数控制对象复制的过程。本篇文章将介绍复制构造函数。
- 复制构造函数
复制构造函数是什么
复制构造函数首先是一个构造函数,它同所有其他的构造函数一样与类同名,没有返回值。它有一个唯一的参数(错误),是该类类型的引用(一般将它声明为const,源于用于赋值的对象一般不用改变它本身的值)。于是复制构造函数的原型为:
class BOOK { public:BOOK(const BOOK& rhs); //构造函数一BOOK(string &name,float price = 0):_bookName(name),_price(price){}; //构造函数二BOOK():_price(0),_bookName(""){}; //构造函数三 private: float _price ; string _bookName;//.... };
什么时候被调用
复制构造函数在需要复制类对象的时候被调用,这些调用情况可以总结为:
- 根据一个同类型的对象显示或隐式地初始化一个对象。
当定义一个新对象并用一个同类型的对象对它进行初始化的时候,将显式使用复制构造函数,如:
BOOK book1; BOOK book2(book1);
当将该类型的对象传递给函数或从函数返回该类型的对象时,将隐式地调用复制构造函数。
- 作为值传递的实参传递给一个函数。
- 函数返回时复制一个对象。
- 初始化顺序容器中的元素。
如:
vector<string> svec(5);
编译器首先调用string类默认构造函数创建一个临时值,再用复制构造函数将临时值复制到每一个元素。
- 根据元素初始化列表初始化数组元素。
如:
BOOK books[]={string("book1"),string("book2"),string("book3"),BOOK() };
book数组的前三个元素将调用构造函数二进行隐式类型转换(C++隐式类型转换),然后调用复制构造函数进行数组元素的复制。如果类禁止隐式类型转换(构造函数使用了explicit声明),或希望不指定实参或多个实参,需要使用完整的构造函数语法,如数组最后一个元素的初始化。
如果没有为类声明复制构造函数会怎样
如果你没有声明一个复制构造函数,那么编译器会给声明一个。实际上,如果你自己没有声明,编译器会为类声明一个复制构造函数 ,一个赋值操作符以及一个析构函数,此外如果你没有声明任何构造函数的话,编译器也会为你声明一个合成默认构造函数。(错误)所有这些编译器自动生成的类成员函数皆为pubilc 且 inline。(这部分内容可以参考《Effective C++》条款05)编译器创建的复制构造函数单纯地将来源对象的每一个非static成员拷贝到目标对象,这在很多时候是不能满足类需求的,特别是类中含有指针时,这时候就需要我们自己来写复制控制的三个特殊成员函数了。
编译器合成的复制构造函数做了什么
合成复制构造函数的行为是:对每一个非static成员进行逐个成员初始化。成员类型不同,初始化方式不一样:
内置类型(如int):直接复制值。
类类型:调用该类的复制构造函数进行复制。
数组:这个比较特殊,因为我们知道一般不能复制数组,但在类中,复制数组时合成复制构造函数将复制数组的每一个值。
另外,合成复制构造函数对类数据成员的初始化都是放在构造函数初始化列表中进行的。
禁止复制
如果我们想禁止某个类的复制行为,我们当然不会想去定义一个复制构造函数,然而编译器却会自动为我们定义一个,那么到底该如何阻止一个类的复制行为呢?
我们可以将复制构造函数定义为private,不允许用户代码复制该类类型的对象,若进行复制将在编译时发生错误。然而类的友元和成员仍可以进行复制,解决办法是我们可以声明一个private复制构造函数却不进行定义,类成员或友元进行复制尝试时,将在程序运行时发生错误。
总结:为驳回编译器自动提供的机能,可将相应的成员函数声明为private并且不予实现。(具体可参考《Effective C++》条款06 若不想使用编译器自动生成的函数,就该明确拒绝)
转载于:https://www.cnblogs.com/QG-whz/p/4485574.html
C++ 复制控制之复制构造函数相关推荐
- C++复制控制:拷贝构造函数
一.拷贝构造函数是一种特殊构造函数,具有单个形参,该形参(常用const修饰)是对该类类型的引用.与默认构造函数一样 ,拷贝构造函数可由编译器隐式调用.拷贝构造函数应用的场合为: (1)根据另一个同类 ...
- C++独孤九剑第五式——人生几何(对象复制控制)
对酒当歌,人生几何? 譬如朝露,去日苦多. 人的一生可能惊涛骇浪,更可能波澜不惊,这次我们就来探讨一下"对象"(当然各位同学自己的对象不在本次讨论范围之内O(∩_∩)O,课后自己讨 ...
- 派生类的构造函数和复制控制
因为派生类是从基类继承而来的,所以包含了基类的一些成员,所以在写派生类的构造函数和复制控制函数时,必须考虑基类的影响. 先说构造函数,派生类的构造函数中,并不直接初始化基类的成员,而是调用基类的构造函 ...
- C++Primer笔记之复制控制
复制控制这一节需要注意的地方不多,主要有以下几点: 1.定义自己的复制构造函数 什么时候需要定义自己的复制构造函数,而不用系统提供的,主要遵循以下的经验说明: 某些类必须对复制对象时发生的事情加以控制 ...
- 12.2 数据库控制文件复制到ASM磁盘组
1 描述 当前数据库t12csia1 参数文件与控制文件皆在文件系统上. 本文档目的是将数据库参数文件与数据库控制文件都放入asm中去. ASM实例有两个磁盘组DATA 和 RECOED02, 将文 ...
- 41 SD配置-销售凭证设置-销售单据到销售单据的复制控制
业务背景:销售单据到销售单据的复制控制 事务码:VTAA SPRO路径:SPRO->销售和分销->销售->维护销售凭证的复制控制 第1步,SPRO进入 第2步,选择"复制控 ...
- C++编程实现多显示器控制(复制、横屏、纵屏,显示器个数)等
需求的提出: 最近做了个三维的程序,部署到客户机器上,客户看了后,现场提出这样的一个需求:程序能智能探测接入的显示器个数,当有新的显示器接入时,现有的只在一个显示器上显示的三维场景能投递到新插入的显示 ...
- php5对象复制、clone、浅复制与深复制的区别与介绍
对象复制的由来 为什么对象会有"复制"这个概念,这与PHP5中对象的传值方式是密切相关的,让我们看看下面这段简单的代码 PHP代码 * /** * * 电视机类 ...
- mysql 5.7配置多线程复制,MySQL5.7复制功能实战,基于事务的复制,多源复制和多线程复制配置...
这篇是幕课网-MySQL5.7复制功能实战视频教程的学习笔记.http://www.imooc.com/learn/589 第1章 MySQL复制基础 MySQL是异步复制 采取针对特定用户的读写分离 ...
最新文章
- linux 网络编程 ping,Linux 网络编程基础(4) -- Ping 的C代码实现
- 【Java8新特性】浅谈方法引用和构造器引用
- 零基础入门学习Python(36) 类和对象:继承
- 圆头像 微信小程序 绘图_小程序canvas绘制圆形微信头像
- opencv 最大内接矩形笔记
- linux下载软件后环境变量配置(最详细的保姆教程)——怎么找到linux下文件的路径
- mysql 数据库操作语句_mysql数据库操作语句大全
- oracle 运维案例,运维注意事项及案例讲解(个人心得)
- 互联网日报 | 3月7日 星期日 | 《你好,李焕英》成中国影史票房亚军;丰巢新增智能存包柜业务;特斯拉推出内部社交平台...
- 21.5 windows_21_Library_use_DLL_Invoke 动态库补充5
- 为什么空集是集合的子集_「离散数学」1.41.5特殊的集合和集合的计算
- php cpu型号,linux如何查看cpu型号?
- php的慢查询,慢查询是什么
- Excel图表如何更改坐标轴最大值
- tushare基本用法
- 遗传算法matlab_【优化求解】遗传算法解决背包问题
- Bootstrap 3 学习
- 适合编程初学者的开源项目:小游戏2048(微信小程序版)
- 贴片LED不良品的常见问题分析
- 腾讯 2020年新增 20 亿行代码,C++蝉联腾讯最受欢迎的编程语言
热门文章
- python textwrap_python2.7.3编译python模块学习- textwrap 文本包装和填充
- python函数参数定义顺序_[python]函数默认参数顺序问题
- jupyter命令把.ipynb文件转化为.py文件
- tf.summary.scalar()和tf.summary.histogram
- L1、L2损失 和 L1、L2正则化
- kafka集群原理介绍
- Apache Spark 2.0: 机器学习模型持久化
- javaweb学习总结(二十三):jsp自定义标签开发入门
- NETBEANS_RUBYROR shortcut
- C# WinForm开发系列 - ToolBar/OutlookBar/Tab/Wizard(转载)