3.异常安全的赋值运算符重载

本文介绍如何为CMyString类型添加赋值运算符,包括经典解法及考虑异常安全的解法。经典解法关注自身赋值检查,但未处理内存分配失败的情况;改进后的解法通过构造临时对象并在成员交换中确保了异常安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、题目

  如下为类型CMyString,请为该类型添加赋值运算符函数。

 1 class CMyString
 2 {
 3 public:
 4     CMyString(char* pData)
 5     {
 6         m_pData = new char[strlen(pData) + 1];
 7         strcpy(m_pData, pData);
 8     }
 9 
10     CMyString(): m_pData(NULL) {}
11 
12 
13     CMyString(const CMyString& str);
14     
15     ~CMyString()
16     {
17         delete []m_pData;
18     }
19 
20     CMyString& operator =(const CMyString& str);
21 
22     void Print() const
23     {
24         printf("%s\n", m_pData);
25     }
26 
27 
28 private:
29     char* m_pData;
30 };

二、经典解法

  经典解法代码实现如下:

 1 CMyString& CMyString::operator =(const CMyString &str)
 2 {
 3     // 自身赋值
 4     if (this == &str)
 5         return *this;
 6 
 7 
 8     m_pData = new char[strlen(str.m_pData) + 1]; // 加一,为存放字符串的结束符'\0'
 9     strcpy(m_pData, str.m_pData);
10 
11     return *this;
12 }

  这是一个经典的解法,为了防止自身赋值,先判断复制对象,是否是自身,如果是,则什么都不做。这个方法可以应对常规的情况。但是,其没有考虑异常安全。在这里的

new char[],可能会由于内存不足导致其抛出异常。

三、考虑异常安全的解法

  实现代码如下:

 1 CMyString& CMyString::operator =(const CMyString &str)
 2 {
 3     if (this != &str)
 4     {
 5         CMyString strTemp(str);
 6 
 7         char* pTemp = strTemp.m_pData;
 8         strTemp.m_pData = m_pData;
 9         m_pData = pTemp;
10     }
11 
12     return *this;
13 }

  在该赋值函数中,如果判断不是自身赋值,那么先用拷贝构造函数以str构造一个临时对象strTemp,此时对于char的内存分配转移到临时对象的拷贝构造函数中,如果抛出异常,那么对于该实例本身来说,没有任何改变,不影响该实例本身的使用。如果临时对象没有出异常,那么将实例自身的m_pData和strTemp.m_pData交换,由于strTemp是临时对象,在作用域结束时,自动调用析构函数,释放内存,而此时的strTemp的m_pData已经指向了原实例的m_pData的内存。这样就能自动释放内存了。同时也是异常安全的。

  

转载于:https://www.cnblogs.com/wangjzh/p/4355514.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值