面试题1:复制运算符

这道题考察了赋值运算符函数,考虑四点:

1:返回值类型为引用类型

2:传入参数声明为常量引用,这样做的好处是避免无谓消耗:如果参数不是引用而是实例,那么从形参到实参会调用一次复制构造函数,降低了代码效率;

3:给实例分配新内存之前,要释放实例自身占据的内存,否则将造成内存泄露;

4:要考虑传入的参数和*this是否是同一个实例。

代码如下:

#include<iostream>
#include <string>
using namespace std;
class CMyString
{
public:
	CMyString(char* pdata=nullptr);
	CMyString(const CMyString& str);
	CMyString& operator=(const CMyString &str);
	~CMyString(){delete[] m_pData;}
	void print(){printf("%s\n",m_pData);}
private:
	char* m_pData;
};
CMyString::CMyString(char* pdata)
{
	if (pdata==nullptr)
	{
		m_pData=nullptr;
		return;
	}
	m_pData=new char[strlen(pdata)+1];
	strcpy(m_pData,pdata);
}
CMyString::CMyString(const CMyString& str)
{
	m_pData=new char[strlen(str.m_pData)+1];
	strcpy(m_pData,str.m_pData);
}
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;
	//能实现功能,但是没有考虑到异常安全
	/*if (this==&str)
	{
		return *this;
	}
	else
	{
		delete[] m_pData;
		m_pData=nullptr;
		m_pData=new char[strlen(str.m_pData)+1];
		strcpy(m_pData,str.m_pData);
		return *this;
	}*/
}
int main()
{
	printf("test01\n");
	char text[]="add";
	CMyString a(text);
	CMyString b,c;
	//连续赋值
	c=b=a;
	c.print();
	//赋值给自己
	c=c;
	c.print();

	cin.get();
}

这里的赋值运算符函数写了两种,下面那个没有考虑异常安全,在new char[]的过程中,有可能因为内存不足抛出异常,而在new上面又是delete[]操作,这样m_pData就成为了空指针,容易导致程序奔溃。

有两种思路解决这个问题

第一种:先new分配新内容再delete,这样就算分配内存失败也不会修改CMyString的实例;

    char * pTemp = new char[strlen(str.m_pData) + 1];  
    delete[] m_pData;  
    m_pData = NULL;  
    m_pData = pTemp;  
    strcpy(m_pData, str.m_pData);  
    return *this;  

第二种:程序中的上面那个写法。strTemp是局部变量,if函数执行完成后变自动释放,strTemp.m_pData所指向的内存也自动释放,因此无需delete

if (this!=&str)
	{
		CMyString strTemp(str);
		char* pTemp=strTemp.m_pData;
		strTemp.m_pData=m_pData;
		m_pData=pTemp;	
	}
	return *this;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值