拷贝控制的部分知识点

本文详细探讨了C++中类的析构函数、拷贝构造函数和拷贝赋值函数的重要性,尤其是在处理动态内存和指针时。讨论了如何正确处理行为像值和行为像指针的类,以及交换操作和左值/右值的区别,强调了自定义swap函数在特定场景的应用。
摘要由CSDN通过智能技术生成

一、三五法则:类需要析构函数的时候,同样也需要拷贝构造函数和拷贝赋值函数。类需要拷贝构造函数和拷贝赋值函数的时候,不一定需要析构函数。如果一个类需要拷贝构造函数,肯定也需要拷贝赋值函数(反之亦然)。

1.需要析构的时候例子:比如类的成员有指向动态内存的内置指针,生成析构函数对指针释放只是简单的销毁,不会delete对应的内存。

此时如果使用了生成拷贝构造函数时,就会简单的复制了类的指针,此时两个类对象的指针就会指向同一个堆中的内存。此时我们需要建立一个新拷贝构造函数。

class test
{
public:
	test();
	test(const test& hp);
	test& operator=(const test &hp);
	~test(){delete ps;}
private:
	int* ps;
};

test f(test hp) {
	test ret = hp; //代码段结束后hp和ret都会被销毁,此时会对成员指针销毁delete两次
	return ret;
}
//合成赋值构造函数如下
test& test::operator=(const test& hp) {
	test a;
	a.ps = hp.ps;
	return a;
}

//此时自定义它的拷贝构造和拷贝赋值函数来解决上面的错误
test::test(const test& hp) {
	this->ps = new int(*hp.ps);
}
test& test::operator=(const test& hp) {
	test a;
	a.ps = new int(*hp.ps);
	return a;
}

2.如果一个类需要拷贝构造函数,肯定也需要拷贝赋值函数(反之亦然)。

二、阻止拷贝的情况

三、拷贝控制

1.行为像值的类

如果一个类有指针成员,则它的行为要像值时要需要遵循以下规则,

并且拷贝赋值运算时必须要先拷贝指针到临时对象再销毁,然后才能赋值,否则就可能发生以下情况:

2.行为像指针的类

这种行为有一种方法是用类成员的一个指针来实现引用计数,类要遵循以下原则:

此时的拷贝赋值成员函数要注意:先增加右值引用计数,再减少左侧引用计数(即析构函数体),最后进行赋值和返回。

四、交换操作

1.类的自定义类类型交换swap函数的调用优先度大于标准库的swap函数,在类参与了重拍元素顺序的算法时,因为在这个算法需要交换两个对象的元素时会调用swap。

编写自己的swap函数,

上面例子中,交换的是内置指针和内置int成员,同时类没有定义内置类类型的swap,所以使用的是标准库的swap。

在以下例子中,如果使用类类型的swap,则以下是错误的。

错误原因在于交换Foo就会交换成员HasPtr,而交换HasPtr需要特殊的HasPtr类型swap,这里却用的标准库swap。

2.在赋值运算符中使用swap

如果类定义了swap成员,则类就会使用自己的swap来定义赋值运算符,它使用了拷贝并交换的计数。

这个效果跟之前的赋值运算符中,先拷贝一个右值类对象到temp,(再释放指针,再赋值)=自定义swap,再返回是相同效果。

五、左值和右值盘点

1.左右值

2.右值

3.

4.

5.   

①第一个sorted函数会陷入死循环,因为ret是左值,且外部函数sorted()和内部的sorted()都是针对左值的函数

②第二个sorted()可以正常运行,外部sorted()是针对左值的,而Foo(*this)是右值。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值