笔试面试之安全的赋值操作符
来源:互联网 发布:免费设计装修软件 编辑:程序博客网 时间:2024/06/05 16:36
类CMyString的声明如下:
class CMyString
{
public:
CMyString(char* pData = NULL);
CMyString(const CMyString& str);
~CMyString(void);
CMyString& operator = (const CMyString& str);
private:
char* m_pData;
};
请实现其赋值运算符的重载函数,要求异常安全,即当对一个对象进行赋值时发生异常,对象的状态不能改变。
分析:首先我们来看一般C++教科书上给出的赋值运算符的重载函数:
CMyString& CMyString::operator =(const CMyString &str)
{
if(this == &str)
return *this;
delete []m_pData;
m_pData = NULL;
m_pData = new char[strlen(str.m_pData) + 1];
strcpy(m_pData, str.m_pData);
return *this;
}
我们知道,在分配内存时有可能发生异常。当执行语句new char[strlen(str.m_pData) + 1]发生异常时,程序将从该赋值运算符的重载函数退出不再执行。注意到这个时候语句delete []m_pData已经执行了。也就是说赋值操作没有完成,但原来对象的状态已经改变。也就是说不满足题目的异常安全的要求。
为了满足异常安全这个要求,一个简单的办法是掉换new、delete的顺序。先把内存new出来用一个临时指针保存起来,只有这个语句正常执行完成之后再执行delete。这样就能够保证异常安全了。
下面给出的是一个更加优雅的实现方案:
CMyString& CMyString::operator =(const CMyString &str)
{
if(this != &str)
{
CMyString strTemp(str);
char* pTemp = strTemp.m_pData;
strTemp.m_pData = m_pData;
m_pData = pTemp;
}
return *this;
}
该方案通过调用构造拷贝函数创建一个临时对象来分配内存。此时即使发生异常,对原来对象的状态没有影响。交换临时对象和需要赋值的对象的字符串指针之后,由于临时对象的生命周期结束,自动调用其析构函数释放需赋值对象的原来的字符串空间。整个函数不需要显式用到new、delete,内存的分配和释放都自动完成,因此代码显得比较优雅。
转贴自:http://zhedahht.blog.163.com/blog/static/25411174200741543224391/
- 笔试面试之安全的赋值操作符
- C++常见笔试面试题目:string类的拷贝赋值运算符函数
- 程序员面试100题之十五 和 三十, 含有指针成员的类的拷贝(异常安全的赋值运算符重载)
- 360移动安全岗位实习生笔试和面试之旅
- C++异常安全的赋值运算符重载 【微软面试100题 第五十五题】
- 单链表的各种操作 笔试 面试
- 笔试面试常见的链表操作
- C++之赋值操作符
- c笔试面试 之 不用除法操作实现两个正整数的除法
- c笔试面试 之 不用加法操作(用逻辑运算)实现两个正整数的除法
- c笔试面试 之 不用乘法操作(用逻辑运算)实现两个正整数的除法
- 笔试面试之二叉树的深度
- 笔试面试之字符串的全排列
- 异常安全的赋值运算符函数
- 【JavaScript的赋值操作符】
- 笔试面试那件小事(类的构造、析构、赋值函数)
- 昨天面试遇到的笔试题,关于String操作的。
- 【笔试面试】字符串相关操作
- CPU寄存器
- 判断枚举值是否存在
- strdup
- (C#)多线程-BackgroundWorker组件
- java中前台输入查询条件中包含“’”的处理
- 笔试面试之安全的赋值操作符
- blog迁移通知
- AjaxPro使用说明
- 深入理解socket(转)
- 金山公司,office成功不了的公司
- 用pushlets实现java comet,长连接技术
- Win32汇编开发环境介绍和RadAsm简明教程
- 关于 vi 中的剪切
- BHO插件的一些资料