C++_001【重载赋值运算符】

【要点】
  • 把返回值类型声明为该类型的引用,并在函数结束前返回实例自身的引用(*this)
  • 把传入的参数类型声明为常量引用,并加上 const 表明不会改变传入的实例的状态
  • 在分配新内存之前释放自身已有内存,否则会导致内存泄漏
  • 在释放自身内存之前,需要进行判断传入的参数和当前的实例(*this)是不是同一个实例,若是同一个实例,则直接返回
【1】主体代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

class CMyString
{
public:
	CMyString(const char* pData = nullptr); //构造函数1
	CMyString(const CMyString& str); //构造函数2
	~CMyString(void); //析构函数
	
	CMyString& operator = (const CMyString& str);//重载赋值运算符
	
	void Print(); //打印信息(m_pData的值)

private:
	char* m_pData;  //存储新值
};

//构造函数,如果传进来的是指针,则需要判断指针是否为空
CMyString::CMyString(const 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]; //申请空间,长度为传进来的指针的长度+1
		//strcpy(m_pData, pData);
		strcpy_s(m_pData, strlen(pData) + 1, pData); //用 strcpy_s 进行复制更加安全
	}
}

//构造函数,如果传进来的是引用,则不需要判断引用是否为空,因为引用必须初始化
CMyString::CMyString(const CMyString &str) {
	int length = strlen(str.m_pData);
	m_pData = new char[length + 1]; //申请空间,同理
	//strcpy(m_pData, str.m_pData);
	strcpy_s(m_pData, strlen(str.m_pData) + 1, str.m_pData);
}

//析构函数
CMyString::~CMyString() {
	delete[] m_pData; //删除指针,释放内存
}

//重载赋值运算符
//加上const,则对于const或非const的实参,函数都能接受
//参数引用的作用是,避免在函数调用时对实参的拷贝,提高效率
CMyString& CMyString::operator = (const CMyString& str) {
	if (this == &str) return *this; // delete释放自身已有内存,释放前需判断传入的是否是同一个实例

	delete[]m_pData; //释放自身已有内存
	m_pData = nullptr;

	m_pData = new char[strlen(str.m_pData) + 1];
	strcpy_s(m_pData, strlen(str.m_pData) + 1, str.m_pData);

	return *this; //返回(*this),可以进行连续赋值,如 str1=str2=str3
}

void CMyString::Print() {
	printf("%s", m_pData); //据说 printf 比 cout 的效率高
}
【2】测试代码
void Test1() {
	printf("Test1 begins:\n");

	//const 常量指针
	const 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");

	const 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");

	const 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[]) // C 中类似于 Java 的形式
{
	Test1();
	Test2();
	Test3();
	return 0;
}
【3】结果输出
Test1 begins:
The expected result is: Hello world.
The actual result is: Hello world.

Test2 begins:
The expected result is: Hello world.
The actual result is: Hello world.

Test3 begins:
The expected result is: Hello world.
The actual result is: Hello world.
The expected result is: Hello world.
The actual result is: Hello world.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值