第十三章 13.2.1节练习

本文详细解析了拷贝构造函数和拷贝赋值运算符在不同场景下的行为,包括析构函数的缺失对内存管理的影响,以及在使用智能指针时如何正确实现拷贝构造函数和赋值运算符以避免资源泄露或意外释放。通过具体的代码示例,展示了如何在StrBlob类中实现这些功能,确保资源的有效管理。

练习13.23

比较上一节练习中你编写的拷贝控制成员和这一节中的代码。确定你理解了你的代码和我们的代码之间的差异(如果有的话)。

解答:

这道题的解答建立在你对13.22题的实现上面,如果个人实现了,可以进行对比。


练习13.24

如果本节中的HasPtr版本未定义析构函数,将会发生什么?如果未定义拷贝构造函数,将会发生什么?

解答:

1. 如果没有定义析构函数的话,会造成内存泄露。因为,成员变量ps是通过new操作在堆上显式分配出的一段内存,需要使用delete显式的去释放。

2. 如果没有定义拷贝构造函数的话,可能会造成二次释放,或使用悬空指针的情况。因为,在合成的赋值运算符中,让不同实例的ps指向同一段内存的起始位置。当其中有一个实例对内存进行释放或其他操作时,别的实例也会受到印象,如果只是修改值之类的操作,影响并不是很大(不至于崩溃);但是,当有释放的操作时,程序很可能会发生崩溃。


练习13.25

假定希望定义StrBlob的类值版本,而且希望继续使用shared_ptr,这样我们StrBlobPtr类就仍能使用指向vector的weak_ptr了。你修改后的类将需要一个拷贝构造函数和一个拷贝赋值运算符,但不需要析构函数。解释拷贝构造函数和拷贝赋值运算符必须要做什么。解释为什么不需要析构函数。

解答:

这里StrBlob使用的是share_ptr智能指针,也就无需像HasPtr那样做出开辟新空间的行为了,需要做的只是直接赋值就可以了,这样只会增加share_ptr的引用数,而不用担心多次释放的问题(只要不适用get,进行对指针的显式释放)。

不需要析构函数是指,直接使用默认的析构函数就可以了,因为shared_ptr是一个类,可以自行管理销毁,不需要显式的去释放。其他的成员变量,都是在栈中创建,在生命周期结束的时候,也就会销毁。所以,默认的析构函数足矣。


练习13.26

对上一题中描述的StrBlob类,编写你自己的版本。

解答:

大概就是这样了

    StrBlob& operator=(const StrBlob& ori){
      data = ori.data;
      return *this;
    }

    StrBlob(const StrBlob& ori):data(ori.data){}

我的实现是共用指针的方式,这样多个实现拷贝的话,是对同一buffer进行修改,这样有悖常理。

这里参考 weixin_38311536 的实现(评论中也有)
StrBlob(const StrBlob& sb) :data(make_shared<vector<string>>(*sb.data)) {}   //拷贝构造函数  
StrBlob& StrBlob::operator= (const StrBlob& sb)  //拷贝复制运算符  
{  
    shared_ptr<vector<string>> p = make_shared<vector<string>>(*(sb.data));  
    data = p;  
    return *this;

}  




评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值