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 ...
随机推荐
- HDU 3336 Count the string(next数组运用)
Count the string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- caffe调loss方法
正文 what should I do if... ...my loss diverges? (increases by order of magnitude, goes to inf. or NaN ...
- awk常见用法
awk作为linux字符搜索,结果统计的实用工具,其在linux日常运维中有着很多的巧妙运用.下面就来技术一下刚刚学到的技巧 #awk命令统计文件夹下所有文件大小 ls -l |awk 'BEGIN ...
- 【Arduino】Arduino接收字符串
[Arduino]Arduino接收字符串 相关文章 [Arduino]开发入门[十]Arduino蓝牙模块与Android实现通信 在[Arduino]开发入门[十]Arduino蓝牙模块与Andr ...
- loadrunner场景报错:Error: CCI compilation error -/tmp/brr_5d65oV/netdir/E/\320\324/Action.c (318): undeclared identifier `LAST'解决思路
在windows下写的脚本编译通过 但是拿到linux agent场景执行中就会提示如下,同样的脚本在windows agent下没有任何问题 agent连的是linux负载机 通过脚本一行一行排查, ...
- 如何使用maven进行avro序列化
maven导入avro: <dependency> <groupId>org.apache.avro</groupId> <artifactId>avr ...
- c#生成连续单号
bill.BillCode = GetBillCode("JH");//生成单号 if (bill.BillCode == "no") { bill.BillC ...
- scrapy meta不用pipe用命令-o
1. spider代码: # -*- coding: utf-8 -*- import scrapy from tencent1.items import Tencent1Item import js ...
- execution(* com.sample.service.impl..*.*(..))
execution(* com.sample.service.impl..*.*(..)) 解释如下: 符号 含义 execution() 表达式的主体: 第一个”*“符号 表示返回值的类型任意: c ...
- 做项目单个功能的时候要理解需求和sql语句。
做项目单个功能的时候要理解需求和sql语句.最好直接按照给出来的sql语句或者存储过程来写,避免有极其细微的差别所造成的不同. 做宜春国税二期的时候有个功能叫夜间开票情况,钻取明细时由于没理解sql语 ...