【无标题】

文章探讨了构造函数和析构函数的作用,强调了拷贝构造的重要性,特别是深拷贝与浅拷贝的区别。以Date类和Stack类为例,解释了为何Date类可以省略拷贝构造函数,而Stack类需要,以及参数引用和const的关键作用。
摘要由CSDN通过智能技术生成

构造函数和析构函数


文章目的

案例

这里还是Date类为例

class Date
{
public:
	//无参构造(利用了缺省参数)
	Date(size_t year = 2023, size_t month = 10, size_t day = 22)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	//可省略,因为全是内置类型
	Date(const Date& d)
	{
		cout << "Date(Date& d)拷贝构造" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}


	~Date()
	{
		_year = 0;
		_month = 0;
		_day = 0;
	};

private:
	size_t _year;
	size_t _month;
	size_t _day;
};


class Stack
{
public:
	//构造函数...

	~Stack()
	{
	free(_ptr);
	_ptr = nullptr;
	}
private:
	int* _ptr;
	int _top;
	int _capacity;
}
说明这几个构造函数为什么
Date(const Date& d)


拷贝构造函数

拷贝构造函数的主要用途:为了解决两个指针指向同一片地址导致二次析构
对于这里的日期类可以不写拷贝构造函数,只依靠值拷贝(浅拷贝就能完成)。
对于上述给出的Stack类就要有自己的拷贝构造,如Stack st2(st1) .将st1赋值给st2,如果还依靠先前的浅拷贝,就会导致st1._ptrst2._ptr指向同一片内存地址,当程序结束(或除了各自当前的作用域时)各自调用析构函数,由于两个对象中的_ptr指向同一片内存地址,无论谁现调用了析构函数,剩下的那个对象在调用析构函数时因为无法对同一片内存空间free()两次,所以就出了问题。
那么问题就出来了,到底还是析构函数中的free()导致的,可是对于指针变量我们不能不写,否则会浪费很大资源,因此,针对这种情况产生了构造函数(深拷贝),构造函数出现后,st1._ptrst2._ptr不在指向同一片空间,后者不仅复制前者的资源,还会根据前者的大小自己开辟地址存放复制过来的资源。

1.格式 为:className (className& object)
因此对于Date(Date d)这种写法首先在语法上就不合格,编译器直接报错,无法通过编译。其次这种写法在调用时会引起无穷递归。这里无法通过编译,所以我没法演示。

2.为什么参数要加引用:
这主要是引用可以防止无穷递归,避免上述那种情况

3.为什么要加const

Date( Date& d)
	{
		cout << "Date(Date& d)拷贝构造" << endl;
		d._year = _year; //修改处
		_month = d._month;
		_day = d._day;
	}
这里把原来`_year = d._year;`
改成d._year = _year; //修改处
如此一来不仅没改变*this,反而改变了传进来的参数,偷鸡不成蚀把米;
为了防止这种情况加了const,用以保护参数d

4.操作符、函数重载返回值要不要加引用
加还是不加的根据:加了就在出作用域时少一次拷贝,不加,在返回值那里会调用一次拷贝构造,以保留结果。

看下面两个例子感受一下

Date& operator+=(int day)
{
	//...具体实现
	return *this;
}
反回值类型为Date& 因为+=返回左操作数,即d1,而d1在main()中,所以除了此函数d1仍然存在,不需要拷贝。
倘若这里反回值类型为Date,那么在最后代码走到return tmp;先调用拷贝构造将*this传回main(),再调用析构函数,与上述相比回多一次拷贝构造的调用,也许在这里不明显,倘若遇到数据庞大、结构复杂的多一次拷贝就多浪费许多资源。

Date operator+(int day)
{
	Date tmp(*this);
	//...具体实现
	return tmp;
}
反回值类型为Date, 因为+=返回新的对象,而这个新对象在此函数中产生,所以需要调用拷贝构造以保留。
倘若这里反回值类型为Date&,那么在最后代码走到return tmp;直接调用析构函数,main()中的d1没有任何改变。
Date d1;
d1+=20;
Date d2 = d1+10

先到这里,有点乱,后续更新

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值