c++类的拷贝,构造,析构函数小练习

对应的是c++primer 第五版P447的练习13.13
代码里加入了一些自己的理解,分享另一种思考问题的方法

#include <iostream>
#include <vector>
using namespace std;
struct X {
	X() { cout << "X()" << endl; }
	X(const X&) { cout << "X(const X&)" << endl; }
	X& operator=(X& g) 
	{ 
		cout << "X& operator=(const X&)" << endl;
		return *this;
	}
	~X()
	{
		cout << "~X()" << endl;
	}
}a,b;
int function(X a,X &b)
{
	return 0;
}
int main()
{
	function(a, b);//传递参数时a拷贝构造,不是拷贝赋值,函数调用结束局部变量a离开了作用域调用了析构函数,而引用b还在
	X* p = new X(a);//new X(a)时,在new分配的动态空间里发生了 拷贝构造(new分配一个X类型的动态空间,用a构造初始化)所以输出"X(const X&)"
	vector<X> vec = { *p };//这里输出了两次"X(const X&)",说明调用了两次拷贝构造函数,
						   //第一次为=右边花括号初始化类产生的(联想一下基类的初始化 struct ={})*p指向的类作为参数传递给拷贝构造函数产生一个临时的类对象(说明vector有能接受一个元素的构造函数)
						   //这里有一个比较重要的知识点:编译器跳过了拷贝赋值函数,直接调用拷贝构造函数例如
						   //string null_book="999-99999";
						   //改写为
						   //string null_book("999-99999");
						   //这里很明显编译器跳过了拷贝赋值函数,直接进入拷贝构造函数
						   //对vec里的元素进行拷贝构造(这个临时对象很快就被析构了)注意虽然=右边是类对象,但是没有调用operator=函数
						   //第二次为vector容器里X类型元素的初始化,初始化完之后析构上面提到的临时变量
						   //拷贝构造函数会逐元素地拷贝一个数组类型的成员,如果数组元素是类类型,则使用元素的拷贝赋值函数来进行拷贝
	a = { *p };//这里调用了operator=拷贝赋值函数而且没有调用析构函数说明没有临时变量产生,推测表达式可以换为 a=*p ,说明vector和普通的类在花括号的使用上面还有区别
	a = b;//调用拷贝赋值函数(operator=),类似shared_ptr之间的拷贝(shared_ptr本来就是一个类,= 左边的引用计数减一,右边加一)注意不会析构a,a依然存在
	delete p;
}
```cpp
#include <iostream>
using namespace std;
struct st {
	st(int i,int j,int k):i(i),j(j),k(k) { cout << 114514; }
	~st() { cout << 1919810; }
	int i, j, k;
};
int main()
{
	st s1 = { 1,2,3 };//相当于调用st s(1,2,3);
	st s2(1, 2, 3);//结果相同
	//所以这就很好地解释了为什么vector<X> vec = { *p };这个语句调用的是拷贝构造函数 X(const X&) 而不是拷贝赋值函数 X& operator=(X& g)  花括号转换为了圆括号 执行拷贝构造函数
	//而a = { *p }单纯忽略了括号,直接执行拷贝赋值函数
}
``

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值