C++知识点:拷贝构造函数例子
//拷贝构造函数:
//函数参数传递时调用一次拷贝构造函数,给对象赋值时调用一次拷贝构造函数,对象作为参数传递后会被及时销毁。
#include <fstream>
#include <string>
using namespace std;
ofstream out("HowMany2.out"); class HowMany2
{
string name;//object identifier
static int objectCount;
public:
HowMany2(const string& id = "") : name(id)
{
++objectCount;
print("HowMany2()");
}
~HowMany2()
{
--objectCount;
print("~HowMany2()");
}
// the copy-constructor;
HowMany2(const HowMany2& h) : name(h.name)
{
name += " copy";
++objectCount;
print("HowMany2(const HowMany2&)");
}
void print(const string& msg = "") const
{
if (msg.size() != )
{
out << msg << endl;
}
out << '\t' << name << ":" << "objectcount=" << objectCount << endl;
}
}; int HowMany2::objectCount = ;
//pass and return By value:
HowMany2 f(HowMany2 x)
{
x.print("x argument inside f()");
out << "Returning from f()" << endl;
return x;
} int main()
{
HowMany2 h("h");
//1.HowMany2()
//2.h:objectCount = 1
out << "Entering f()" << endl;
//3.Entering f()
/*进入f(h)
此时拷贝构造函数被编译器调用,完成传值过程,
在f()内创建了一个新对象,他是h的拷贝,所以对象变成2
输出:
//传递对象作为函数参数时即发生拷贝构造
4.HowMany2(const HowMany2&)
5.h copy :objectcount=2
6.x argument inside f()
7.h copy:objectcount=3
8.returning from f()
第8显示了从f()返回的开始情况,但在局部变量“h拷贝”销毁前
(在函数结尾这个局部变量出了范围)他必须被拷入返回值,也就是h2.
以前未创建的对象h2是从现在的对象(在函数f()内的局部变量创建的)
所以在第9行拷贝构造函数又被调用了。
现在对于h2的标识符,名字变成了h拷贝的拷贝,因为他是从拷贝拷过来的,
这个拷贝是函数f()内部对象,
在对象返回之后,函数结束之前,对象数暂时变为3,但是此后h拷贝被销毁。 */
HowMany2 h2 = f(h);
//在完成对f()的调用后,仅有两个对象h和h2,这是看到h2最终是h拷贝的拷贝
h2.print("h2 after call to f()");
out << "call f() , no return value" << endl;
//从第15行开始调用f(h),这次调用忽略了返回值,在16行可以看到恰好在参数传入之前,
//拷贝构造函数被调用。和前面一样,21行显示了为了返回值而调用拷贝构造函数。但是拷贝构造函数必修
//有一个作为它的目的地址(this指针)的工作地址,但这个地址从哪里来呢?
//每当编译器为了正确地计算一个看不见的对象而需要一个临时对象时,编译器都会创建一个,在这种情况下
//编译器创建一个看不见的对象作为函数f()忽略了的返回值的目标地址。这个临时对象的生存期应该尽可能的短暂,
//这样空间就不会被这些等待被销毁的而且占用资源的临时对象搞乱。在一些情况下,临时对象可能立刻被传递给
//另外的函数,但是现在这种情况下临时对象不再需要,所以一旦调用完毕就对内部对象调用析构函数(23-24)
//这个临时对象被销毁(25-26)
//28-31行,h2,h被销毁
f(h);
out << "After call to f()" << endl;
}
//输出结果:
/*
1.HowMany2()
2.h:objectCount=1
3.Entering f()
//传递对象作为函数参数时即发生拷贝构造
4.HowMany2(const HowMany2&)
5.h copy :objectcount=2
--------------------------
6.x argument inside f()
7.h copy:objectcount=3
8.returning from f()
//返回对象再次调用拷贝构造函数
--------------------------
9.HowMany2(const HowMany2&)
10.h copy copy: objectCount=3
//临时对象使用完毕,析构
11.~HowMany2()
12.h copy : objectcount=2
13.h2 after call to f()
14.h copy copy: objectCount=2
15.call f(),no return value
//f(h)
16.HowMany2(const HowMany2&)
17.h copy: objectcount=3
18.x argument inside f()
19.h copy:objectCount=3
20.Returning from f()
//f(h)后赋值给未知的值,在此调用拷贝构造函数
21.HowMany2(const HowMany2&)
22.h copy copy:objectCount = 4
//临时对象使用完毕再次调用析构函数
23.~HowMany2()
24.h copy : objectCount = 3
//销毁匿名的对象
25.~HowMany2()
26.h copy copy:objectCount=2
27.After call to f()
28.~HowMany2()
29.h copy copy :objectcount=1
30.~HowMany2()
31.h: objectcount=0
*/
C++知识点:拷贝构造函数例子的更多相关文章
- C++ 一个例子彻底搞清楚拷贝构造函数和赋值运算符重载的区别
class TestChild { public: TestChild() { x=; y=; printf("TestChild: Constructor be called!\n&quo ...
- 从一个例子讲解拷贝构造函数与return
#include "iostream" using namespace std; class Location { public: Location(, ) { X = xx; Y ...
- C++ 为什么拷贝构造函数参数必须为引用?赋值构造函数参数也必须为引用吗?
之前写拷贝构造函数的时候,以为参数为引用,不为值传递,仅仅是为了减少一次内存拷贝.然而今天看到一篇文章发现自己对拷贝构造的参数理解有误. 参数为引用,不为值传递是为了防止拷贝构造函数的无限递归,最终导 ...
- PoEdu - C++阶段班【Po学校】- Lesson03-4_构造函数&赋值函数&拷贝构造函数&学习方式 - 第6天
PoEdu - C++阶段班[Po学校]- 第6天 课堂选择题目: 1 关于转换构造函数 ClassDemo demo = 1; 调用转换构造函数 2 关于拷贝赋值函数 demo =2; 首 ...
- C++拷贝构造函数(深拷贝,浅拷贝)
对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. #i ...
- 【转】C++的拷贝构造函数深度解读,值得一看
建议看原帖 地址:http://blog.csdn.net/lwbeyond/article/details/6202256 一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很 ...
- C++拷贝构造函数(深拷贝,浅拷贝)
http://www.cnblogs.com/BlueTzar/articles/1223313.html 对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; ...
- C++拷贝构造函数详解(转载)
一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a = 100; int b = a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员 ...
- 【转】 c++拷贝构造函数(深拷贝,浅拷贝)详解
c++拷贝构造函数(深拷贝,浅拷贝)详解 2013-11-05 20:30:29 分类: C/C++ 原文地址:http://blog.chinaunix.net/uid-28977986-id-3 ...
随机推荐
- MVC开发中的常见错误-01未能加载文件或程序集“EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”或它的某一个依赖项。
错误信息:未能加载文件或程序集“EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”或 ...
- Python关键字及其用法
Python有哪些关键字 -Python常用的关键字 and, del, from, not, while, as, elif, global, or, with, assert, else, if ...
- 页面注册系统--使用forms表单结合ajax
页面注册系统--使用forms表单结合ajax 在Django中通过forms构建一个表单 1.urls.py 配置路由 from django.conf.urls import url from d ...
- linux操作系统中oracle数据库的密码过期问题解决
1:首先确定linux登录的用户是root 切换到数据库用户 su oracle(切记,如果这里su oracle不可以,那么就使用此命令su - oracle,这个命令切换到数据库用户肯定可以成功. ...
- 运维基础——Zabbix 设置Redis监控
https://blog.csdn.net/xundh/article/details/77604357
- 【BZOJ4155】[Ipsc2015]Humble Captains
题解: 第一问裸的最小割 第二问考虑贪心 我们把边权平均分配给两个点 然后就变成了给n个数分两组差最小 np-hard问题 暴力背包,操作存在区间左移,右移,or bieset优化
- 配置文件——节点<machineKey>的作用,强随机生成
<machineKey>这个节允许你设置用于加密数据和创建数字签名的服务器特定的密钥.ASP.NET自动使用它来保护表单验证Cookie,你也可以将它用于受保护的视图状态数据.同时,这个密 ...
- DirectoryEntry配置IIS7出现ADSI Error:未知错误(0x80005000)
一.错误情况 环境:win7+iis7.0 DirectoryEntry配置IIS7出现如下错误 或者是 下面一段代码在IIS6.0下运转正常,但IIS7.0下运转会出错: System.Direct ...
- day5.python列表练习题
写代码,有如下列表,按照要求实现每一个功能 li = [“alex”, “WuSir”, “ritian”, “barry”, “wenzhou”] 1.计算列表的长度并输出 print(len(li ...
- P1378 油滴扩展 dfs回溯法
题目描述 在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界.必须等一个油滴扩展完毕才能放置下一个油滴. ...