本篇是介绍C++的构造函数的第二篇(共二篇),属于读书笔记,对C++进行一个系统的复习。

复制构造函数

复制构造函数是构造函数的一种,也被称为拷贝构造函数,他只有一个参数,参数类型是本类的引用。默认构造函数(即无参构造函数)不一定存在,但是复制构造函数总会存在。因为只要没有自己写的复制构造函数,就会自动生成一个复制构造函数,它只是实现了对应成员之间的一一对应的复制。大多数时候这样一个自动生成的复制构造函数是够用的,但是当涉及到“深拷贝”的需求时还是要自己设计复制构造函数。

构造函数不能以本类的对象作为唯一参数,以免和复制构造函数相混淆。举例子来说就是, CNum(CNum n){}; 这样的构造函数是不允许的。

为什么C++要有这样的机制来保证复制构造函数一定存在呢,因为在很多种情况下都会需要这样的构造函数。

1)当用一个对象去初始化同类的另一个对象时,会调用复制构造函数。

对基本数据类型有这样的用法:

 int a = ;
int b = a;

第二个语句中使用一个int变量初始化了另一个int变量。对象也可以有类似的初始化方法,用一个对象去初始化另一个同类对象。

 CNum n1 = ;
CNum n2 = n1;        //调用复制构造函数

注意,第二个语句是一条初始化语句,调用了复制构造函数。如果分开写成CNum n2; n2 = n1;就不会调用复制构造函数而是调用无参构造函数,然后调用对=运算符的重载函数。

2)当把对象作为实参时,会调用复制构造函数。

对象作为参数时的传参方法是传值,所以进入这样的函数时就需要在栈帧中构造一个形参对象。作为形参的对象是使用复制构造函数初始化的,而且调用复制构造函数时使用的参数,就是调用函数时所给的实参。这一种用法和第三种用法正是必须有复制构造函数的原因。

总之传递的参数是对象时就一定会调用复制构造函数。复制构造函数有可能并不是“忠实地”一一对应的复制,因此“形参值总等于实参值”这句话就不一定对了,是否完全相等取决于复制构造函数是怎样编写的。

要说明的是,把对象作为函数的形参显然是效率较低的做法,建议使用对象的引用作为形参。如果不希望实参被修改,可以在形参前面加const修饰。

3)当返回一个对象时,会调用复制构造函数。

函数返回时到底发生了什么呢,或者说return语句到底发生了什么呢?需要被返回的值是存储在被调用函数(callee)的栈帧(stack frame)中的,但函数返回后callee的栈帧已经不再存在,返回值应该在返回之前被拷贝到一个安全的位置才行。如果是基本类型的返回值,直接的做法是把返回值保存到一个寄存器中,而对对象显然不能这样做(如果不了解寄存器是什么可以忽略这一句),但总之需要把需要返回的对象返回到一个合适的位置,这就要用到复制构造函数。

作为函数返回值的对象,是用复制构造函数初始化的,而调用复制构造函数时的实参就是return语句所返回的对象。

类型转换构造函数

除复制构造函数外,只有一个参数的构造函数一般都可以称为类型转换构造函数,它们可以起到类型自动转换的作用。还是CNum的例子:

 class CNum {

 int num;
public: CNum(){ num = ;}
CNum(int a){ num = a;}
CNum(int a, int b){ num = a + b;}
}

第二个构造函数CNum(int a)就是一个类型转换构造函数。

 CNum n1 = ;        //调用了CNum(int a)

但是实际上如果有这样的语句,结果类似可是过程却完全不一样。

 CNum n1;
n1 = ;

的二条语句也是合法的,而且实际上还调用了CNum(int a),这要说一下 n1 = ; 这条语句是怎么实现的,过程就是先用2作为实参调用CNum(int a);生成一个无名的临时对象,然后把临时对象按成员对应复制给n1。这样做的效率显然低于 CNum n1 = ; 这一条语句。

总之其他类型到对象的转换并不是那么的直接,临时对象的创建需要调用类型转换构造函数,之后再对应赋值。

C++构造函数(二)的更多相关文章

  1. javascript继承之借用构造函数(二)

    //简单的函数调用 function Father() { this.nums= [1,2]; } function Son() { Father.call(this);//调用超类型,完成son继承 ...

  2. javascript中继承(二)-----借用构造函数继承的个人理解

    本人目录如下: 零.寒暄&回顾 一,借用构造函数 二.事件代理 三,call和apply的用法 四.总结 零.寒暄&回顾 上次博客跟大家分享了自己对原型链继承的理解,想看的同学欢迎猛击 ...

  3. C++ 复制控制之复制构造函数

    7月26日更新: 过了这么长的时间回过头来看,发现文章中有几个点说错(用红字标出): 构造函数不是只有唯一一个参数,它也可以是多参数形式,其第二参数及后继以一个默认值供应. 不是没有声明复制控制函数时 ...

  4. <转载>构造函数与拷贝构造函数

    原文地址http://www.cnblogs.com/waynelu/archive/2012/07/01/2572264.html 构造函数 构造函数.析构函数与赋值函数是每个类最基本的函数. 对于 ...

  5. 《Java4Android视频教程》学习笔记(二)

    一:面向对象 1.对象 ①对象的使用方法 对象.变量 对象.方法 ②匿名对象 new A().方法 new A().变量 匿名对象会被分配到对内存中 java内存处理机制会对一定时间内无指针指向的对象 ...

  6. 前端总结·基础篇·JS(三)arguments、callee、call、apply、bind及函数封装和构造函数

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...

  7. Java基础---IO(二)--File类、Properties类、打印流、序列流(合并流)

    第一讲     File类 一.概述 1.File类:文件和目录路径名的抽象表现形式 2.特点: 1)用来将文件或文件夹封装成对象 2)方便于对文件与文件夹的属性信息进行操作 3)File类的实例是不 ...

  8. 菜鸟学Java(十五)——Java反射机制(二)

    上一篇博文<菜鸟学编程(九)——Java反射机制(一)>里面,向大家介绍了什么是Java的反射机制,以及Java的反射机制有什么用.上一篇比较偏重理论,理论的东西给人讲出来总感觉虚无缥缈, ...

  9. c++——对象的构造和析构函数、构造函数的分类及调用

    1构造函数和析构函数的概念 有关构造函数 1构造函数定义及调用 1)C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数: 2)构造函数在定义时可以有参数: 3)没有任何 ...

  10. mfc 带参数的构造函数

    知识点 默认的构造函数 带参数的构造函数 重载构造函数 一.默认的构造函数 二.带参数的构造函数 三.重载构造函数 class Tdate { public: int year;//年 int mon ...

随机推荐

  1. Java ssh 框架 hibernate 详细理解

    Hibernate框架技术相信对大多数的 java 程序员并不陌生,数据表之间的关系如何通过Hibernate来建立,需要我们认真的分析数据表中数据项之间的交互: 数据库表的之间的关系有: (1)一对 ...

  2. [Day03] 循环语句、list相关练习题

    用户输入两个数,求平均值. 让用户一直输入数字,如果输入的是'0',终止程序打印所有数字之和. 让用户一直输入数字(只输入数字),如果没输入任何值,终止程序打印所有输入数字的平均值. 求出这个list ...

  3. ES6之"let"能替代"var"吗?

    译者按: 使用let的确会比var安全很多. 原文: Why You Shouldn't Use 'var' Anymore 译者: Fundebug 为了保证可读性,本文采用意译而非直译. 我已经使 ...

  4. iOS 详解NSObject协议

      协议就是一组接口的集合,遵守一个协议之后就拥有的该协议中所有方法的声明.NSObject这个类遵守了NSObject协议,并且实现了NSObject协议里的所有方法,所以NSObject类及其子类 ...

  5. POJ1006: 中国剩余定理的完美演绎(非原创)

    问题描述 人自出生起就有体力,情感和智力三个生理周期,分别为23,28和33天.一个周期内有一天为峰值,在这一天,人在对应的方面(体力,情感或智力)表现最好.通常这三个周期的峰值不会是同一天.现在给出 ...

  6. SSH免密码(日志三)

    上一篇:JDK安装以及安装过程中出现的问题(日志二) 原理,就是RSA加密,含有公钥和私钥,具体言之,用公钥来确认请求人是否是私钥的持有人. 1, 2, 3, 4, ssh免密码过程中遇到的问题:需要 ...

  7. [刷题]算法竞赛入门经典 3-1/UVa1585 3-2/UVa1586 3-3/UVa1225

    书上具体所有题目:http://pan.baidu.com/s/1hssH0KO(我也是在网上找到的pdf,但不记得是从哪里搜刮到的了,就重新上传了一遍) PS:第一次写博客分享我的代码,不知道我对c ...

  8. Java学习笔记——浅谈数据结构与Java集合框架(第一篇、List)

    横看成岭侧成峰,远近高低各不同.不识庐山真面目,只缘身在此山中. --苏轼 这一块儿学的是云里雾里,咱们先从简单的入手.逐渐的拨开迷雾见太阳.本次先做List集合的三个实现类的学习笔记 List特点: ...

  9. vue1.0和vue2.0的区别(二)

    这篇我们继续之前的vue1.0和vue2.0的区别(一)继续说 四.循环 学过vue的同学应该知道vue1.0是不能添加重复数据的,否则它会报错,想让它重复添加也不是不可以,不过需要定义别的东西 而v ...

  10. Swift学习笔记(4):字符串

    目录: 初始化 常用方法或属性 字符串索引 初始化 创建一个空字符串作为初始值: var emptyString = "" // 空字符串字面量 var anotherEmptyS ...