剑指offer--1.实现赋值运算符函数

问题描述

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

class CMyString
{
private:
	char* m_pData;
public:
	CMyString(char* pData = nullptr);
	CMyString(const CMyString& str);
	~CMyString();
};
解题思路
经典解法,初级程序员
  1. 返回引用以便连续赋值
  2. 传入常量引用:非引用的话,形参到实参会调用一次复制构造函数,产生无谓消耗
  3. 释放实例自身已有的内存
  4. 判断传入的参数和当前的实例(*this)是不是同一个实例。如果是,不进行赋值操作,否则释放内存的时候,传入参数的内存也被释放掉了(多个对象指向同一块儿内存,释放要小心!)
CMyString & CMyString::operator=(const CMyString & str)
{
	if (this == &str)//指向同一块儿内存
		return *this;
	delete[] m_pData;
	m_pData = nullptr;

	m_pData = new char[strlen(str.m_pData) + 1];
	strcpy(m_pData, str.m_pData);
	return *this;
}
考虑异常安全性的解法,高级程序员
  1. delete后,new内存不足导致抛出异常,m_pData将是一个空指针,导致程序崩溃(异常不安全)。
    想办法在函数内部,及时抛出异常,程序也能继续执行:
    方法:先创建一个临时实例(自动构造和析构),在交换临时实例和原来的实例,避免了new操作
CMyString & CMyString::operator=(const CMyString & str)
{
	if (this != &str)
	{
		CMyString strTmp(str);
		char* pTmp = strTmp.m_pData;
		strTmp.m_pData = m_pData;
		m_pData = pTmp;
	}
	return *this;
}
测试代码
#include <string>
#include <iostream>
using namespace std;

class CMyString
{
private:
	char* m_pData;
public:
	CMyString(char* pData = nullptr);
	CMyString(const CMyString& str);
	~CMyString();
	CMyString& operator=(const CMyString& str);
	void Print();
};

CMyString::CMyString(char * pData)
{
	if (pData == nullptr)
	{
		m_pData = new char[1];
		m_pData[0] = '\0';
	}
	else
	{
		int length = strlen(pData);
		m_pData = new char[length + 1];
		strcpy_s(m_pData,length + 1, pData);
	}
}

CMyString::CMyString(const CMyString & str)
{
	int length = strlen(str.m_pData);
	m_pData = new char[length + 1];
	strcpy_s(m_pData, length + 1, str.m_pData);
}

CMyString::~CMyString()
{
	delete[] m_pData;
}

CMyString & CMyString::operator=(const CMyString & str)
{
	if (this != &str)
	{
		CMyString strTmp(str);
		char* pTmp = strTmp.m_pData;
		strTmp.m_pData = m_pData;
		m_pData = pTmp;
	}
	return *this;
}

void CMyString::Print()
{
	cout << m_pData << endl;
}

// ====================测试代码====================

void Test1()
{
	printf("Test1 begins:\n");

	char* text = "Hello world";

	CMyString str1(text);
	CMyString str2;
	str2 = str1;

	printf("The expected result is: %s.\n", text);

	printf("The actual result is: ");
	str2.Print();
	printf(".\n");
}

// 赋值给自己
void Test2()
{
	printf("Test2 begins:\n");

	char* text = "Hello world";

	CMyString str1(text);
	str1 = str1;

	printf("The expected result is: %s.\n", text);

	printf("The actual result is: ");
	str1.Print();
	printf(".\n");
}

// 连续赋值
void Test3()
{
	printf("Test3 begins:\n");

	char* text = "Hello world";

	CMyString str1(text);
	CMyString str2, str3;
	str3 = str2 = str1;

	printf("The expected result is: %s.\n", text);

	printf("The actual result is: ");
	str2.Print();
	printf(".\n");

	printf("The expected result is: %s.\n", text);

	printf("The actual result is: ");
	str3.Print();
	printf(".\n");
}

int main(int argc, char* argv[])
{
	Test1();
	Test2();
	Test3();

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值