题目:
如下为类型CMyString的声明,请为该类型添加赋值运算符函数
class CMyString
{
public:
CMyString(char *pData = nullptr);
CMyString(const CMyString& str);
private:
char *m_pData;
};
书中有四个方面的考虑,现总结如下:
1.返回值的类型是否为该类型的引用,并在函数结束前返回实例自身的引用。此处考虑连续赋值时,只有引用才可以连续赋值。
2.是否把传入的参数的类型声明为常量引用。这里是对效率的考虑,如果传入的参数不是引用而是实例,从形参到实参会调用一次构造函数,把传入的参数声明为引用可以避免这样的无谓消耗。
3.是否释放实例自身的已有的内存。如果我们忘记在分配新内存之前释放自身已有的空间。则程序将出现内存泄漏。
4.判断传入的参数和当前的实例(*this)是不是同一个实例。如果不判断就进行赋值操作,当传入的的参数和*this是一个实例时,释放自身内存的同时传入的参数的内存也被释放了,就会找不到需要赋值的内容。
结合以上,给出解法:
/*
1.是否返回引用,只有引用才可以连续赋值
2.是否吧传入的参数类型声明为常量引用
3.是否释放实例自身的内存
4.判断传入的参数是否和当前的实例(*this)是不是同一个实例
*/
CMyString& CMyString::operator = (const CMyString& str)
{
/*
判断是否是同一个实例
*/
if (this == &str)
return *this;
/*
释放自身的内存
*/
delete[]m_pData;
m_pData = new char[strlen(str.m_pData) + 1];
strcpy(m_pData, str.m_pData);
return *this;
}
完整的测试代码:
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
/*
面试题一:赋值运算符函数
题目:如下为类型CMyString的声明,请为该类型添加复制运算符函数
*/
#include "pch.h"
#include<cstring>
#include<cstdio>
#pragma warning(disable:4996)
class CMyString
{
public:
CMyString(char *pData = nullptr);
CMyString(const CMyString& str);
CMyString& operator = (const CMyString& str);
~CMyString();
void Print();
private:
char *m_pData;
};
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(m_pData, pData);
}
}
CMyString::CMyString(const CMyString& str)
{
int length = strlen(str.m_pData);
m_pData = new char[length + 1];
strcpy(m_pData, str.m_pData);
}
CMyString::~CMyString()
{
delete[]m_pData;
}
/*
1.是否返回引用,只有引用才可以连续赋值
2.是否吧传入的参数类型声明为常量引用
3.是否释放实例自身的内存
4.判断传入的参数是否和当前的实例(*this)是不是同一个实例
*/
CMyString& CMyString::operator = (const CMyString& str)
{
/*
判断是否是同一个实例
*/
if (this == &str)
return *this;
/*
释放自身的内存
*/
delete[]m_pData;
m_pData = new char[strlen(str.m_pData) + 1];
strcpy(m_pData, str.m_pData);
return *this;
}
void CMyString::Print()
{
printf("%s", m_pData);
}
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()
{
Test1();
Test2();
Test3();
return 0;
}