当前课程知识点:C++语言程序设计基础 > 第4章 类与对象 > 构造函数 > 复制构造函数调用举例
大家好
欢迎回来继续学习
C++语言程序设计
下面我们就通过一个具体的例子
来看看什么时候会在程序中
发生复制构造
现在我们来看
在这个例子中
首先定义了一个Point类
就像a
接下来定义对象b的时候
用a去初始化b
那用a去初始化b的时候
我们都应该想得到
这个时候应该要调用
复制构造函数的
也叫拷贝构造函数
再往下看
在这个地方用b作实参
对象作实参
去调用了函数fun1
我们看这个函数fun1
它的形参类型是Point类对象
所以形实结合的时候
用实参去初始化形参的时候
应该也会发生一次复制构造
接下来呢
fun2函数的运行结果
复制给对象b
那我们来看这个fun函数
它的结果是一个什么
是一个Point类对象
它把这个局部对象return
返回给调用者
所以在这个返回的过程中
一个局部对象怎么可能
给到它的调用者去呢
在这个过程中
会发生复制构造
构造一个临时无名对象
传给调用者
现在我首先把程序整个运行一遍
大家看一下这个运行效果
然后我再用单步跟踪的方法
跟大家一起跟踪到函数体内部
去分析这个结果是怎么得出来的
那现在我就在主函数的最后一句
最后一个结束大括号之前
在这儿设一个断点
就在这儿点一下
就设了一个断点
然后按这个功能键f5
它就一下就执行完了
那这个时候呢
如果你不设断点
按f5执行完了
这个执行窗口立刻就关掉了
现在这个窗口留在这儿
我们看到调用了三次constructor
就是复制构造函数
为什么会调用三次
复制构造函数呢
接下来我们就用单步运行的方式
来观察一下
好 现在我们先停止调试
再次进入这个主函数
这回我就不一下运行到底了
按f10
用单步执行的方式
进到主函数中去
再执行一步
单步执行
直接构造完成a
好 接下来呢用a作为参数
去初始化b 构造b
这个时候按f11
进到复制构造函数里面
大家看用a去初始化b
调用了复制构造函数吧 对吧
执行完这个复制构造函数以后
那我们看
当前正在构造的对象b
它的x y值都有了
这个a是一样的
接下来呢
输出这个提示信息
我们会看到很多例题里面
会在构造函数
析构函数里写这样一句话
正在调用拷贝构造函数
或者正在调用构造函数析构函数
初学者看到例题你都写这些东西
觉得干吗呀 有什么意思
干吗要写这个信息
这就是作为例题
为了让你执行这个例题的时候
能够看到流程经过了哪些地方
这些提示信息
也叫做调试信息
作为例题是演示给你看的
那么有些时候做开发的过程中
也会写这些调试信息
那么实质上开发工程师
自己能够看到
程序的流程是怎么样
最后交付用户使用的时候
这个信息是不要保留的了
不要让用户用你的软件
经常看到一会构造函数来了
一会析构函数来了
那个是很讨厌的
好 结束这个以后
我们回到主函数中来
现在验证一下
对象b是不是构造好了
所以也调用x
取出来x值输出一下看
是不是0
其实不用输出
我们从调试的这个窗口里面
局部变量这儿也可以看得到
b对象 它的x值是0
我们再执行一步
好 看到这个输出窗口中
确实输出了一个0在这儿
接下来再往下执行
就是调用函数fun1
这个时候用对象作实参
我们看会发生什么
要跟踪到函数里面
当然我们就按f11了
它并不是一下
进到函数fun1里面去
而是进到了
这个复制构造函数里面
为什么呢
因为你要进到fun1之前
先得完成
这个形实结合的参数传递
先得构造这个形参对象
构造这个形参对象
用实参去初始化它的时候
首先就要调用
Point类的复制构造函数
所以就进到这里面来了
进到这里面来了以后
我们看执行这个复制构造
将参数对象的x值
复制给当前x
将参数对象的y值
复制给当前的y
这个执行完了以后
接下来
我们再按个f11
看一下走到哪儿去了
这个时候才进到fun1
也就是说
参数构造完成了
我们看这个时候形参p
它已经有值了
它的x y都有值了
形实结合完成了
执行完这个以后
回到主函数
再走到下一步呢
这个时候要调用fun2
还是用f11跟踪进去
进到这儿来了
构造一个局部对象a
然后这个时候要返回a
返回a的时候呢
我们要看它会不会追踪到
会不会进入到构造函数里面
去构造一个临时无名对象
那我还在这儿按f11
看它去哪儿
果然进到复制构造函数里面了
来构造一个临时无名对象
那么这个临时无名对象
大家看
完成这个x
p点x复制给x
p点y复制给y
这个完成了以后
它x y都是0了 构造好了
这个时候又输出了一遍
Calling the copy constructor
第三次了
那我们来看这个时候
三次copy constructor都有了
好 再回到主函数中
回到这个fun2中
回到主函数中
现在我们来看这儿写着
fun2的返回值
这个是一个对象
这个对象x等于0 y等于0
接下来还要发生一些赋值
有的同学会误会
是不是把这个对象
赋值给b的时候
也调用了复制构造函数呢
不会的
这是赋值 不是构造
b已经存在了
所以给b赋值
不会调用任何构造函数
但是在第八章中我们还要讲
赋值实际上
也是隐含的有一个函数完成的
叫赋值运算符函数
如果我们只实现
这个对应数据程序
一一对应的这种赋值
我们可以用它默认的功能
像这个我按一下f10
它就赋值过去了
大家看b里面的值现在是0
如果我们学习了第八章以后
想定义一种我们自己希望的
特殊的赋值方式
你也可以写一个函数
叫做赋值运算符函数
来实现这个功能
希望大家有兴趣呢
坚持我们学到第八章
就可以自己定义赋值功能了
好 接下来呢
b点x输出一下
也是验证一下
是不是正确得到了这个值
其实不用验证
我们在这儿看到了
已经是这样了
看一下验证结果
确实输出的是0
这个是正确的
那么通过这个例子呢
我想大家就了解了
这三种情况
第一种情况用a初始化b
第二种情况用对象作为实参
第三种情况
函数返回值是对象
这三种情况下
都会调用复制构造函数
-导学
--第1章导学
-计算机系统简介
--计算机系统简介
--计算机系统简介 测试题
-计算机语言和程序设计方法的发展
--计算机语言和程序设计方法的发展 测试题
-面向对象的基本概念
--面向对象的基本概念 测试题
-程序的开发过程
--程序的开发过程
--程序的开发过程 测试题
-信息的表示和储存
--计算机的数字系统
--数据的编码表示
--信息的表示和储存 测试题
-实验指导
-导学
--第二章导学
-C++语言概述
--C++语言概述 测试题
-基本数据类型、常量、变量
--程序举例
--基本数据类型、常量、变量 测试题
-运算与表达式
--运算与表达式 测试题
-实验二:简单程序设计(上)
-数据的输入和输出
--数据的输入和输出
--数据的输入和输出 测试题
-选择结构
--if语句
--switch语句
--选择结构 测试题
-循环结构
--for语句
--循环结构 测试题
-自定义类型
--自定义类型
--自定义类型
-第2章小结
--第二章小结
-实验二:C++简单程序设计(下)
-导学
--导学
-函数定义
--函数定义
--函数定义 测试题
-函数调用
--例3-2
--例3-3
--例3-4
--例3-5
--例3-6
--函数调用 测试题
-嵌套与递归
--例3-9
--例3-10
--嵌套与递归 测试题
-函数的参数传递
--函数的参数传递
--函数的参数传递 测试题
-引用类型
--引用类型 测试题
-含有可变参数的函数
--含有可变参数的函数 测试题
-内联函数
--内联函数 测试题
-constexpr函数
--CONSTEXPR函数课后习题
-带默认参数值的函数
--带默认参数值的函数 测试题
-函数重载
--函数重载 测试题
-C++系统函数
--C++系统函数习题
-第3章小结
--第三章小结
-实验三(上)函数的应用
-实验三(下)函数的应用
-导学
--导学
-面向对象程序的基本特点
--面向对象程序的基本特点 测试题
-类和对象
--类和对象的定义
--类和对象 测试题
-构造函数
--构造函数基本概念
--委托构造函数
--复制构造函数
--构造函数 测试题
-析构函数
--析构函数
--析构函数 测试题
-类的组合
--类的组合
--类的组合程序举例
--前向引用声明
--类的组合 测试题
-UML简介
--UML简介
--UML简介课后习题
-结构体与联合体
--结构体与联合体 测试题
-枚举类
--枚举类
--枚举类 测试题
-第4章小结
--第四章小结
-实验四(上)
--实验四(上)
-实验四(下)
--实验四(下)
-导学
--导学
-标识符的作用域与可见性
--标识符的作用域与可见性 测试题
-对象的生存期
--对象的生存期
--对象的生存期 测试题
-类的静态成员
--类的静态成员 测试题
-类的友元
--类的友元 测试题
-共享数据的保护
--共享数据的保护 测试题
-多文件结构和预编译命令
--多文件结构和预编译命令 测试题
-第5章小结
--小结
-实验五
--实验五
-导学
--导学
-数组的定义与初始化
--数组的定义与使用
--一维数组应用举例
--数组的定义与初始化 测试题
-数组作为函数的参数
--数组作为函数的参数 测试题
-对象数组
--对象数组
--对象数组 测试题
-基于范围的for循环
-指针的定义和运算
--指针的定义和运算 测试题
-综合实例
--综合实例
-实验六(上)
--实验六上
-指针与数组
--指针数组
--指针与数组 测试题
-指针与函数
--指针类型的函数
--指向函数的指针
--指针与函数 测试题
-对象指针
--对象指针
--对象指针 测试题
-动态内存分配
--动态内存分配 测试题
-智能指针
--智能指针
-vector对象
--vector对象
--vector对象 测试题
-对象复制与移动
--移动构造
--对象复制与移动 测试题
-字符串
--C风格字符串
--string类
--字符串 测试题
-第6章小结
--第六章小结
-综合实例
--综合实例
-实验六(下)
--实验六(下)