题目介绍
C++岗位面试题:实现自定义MyString类,实现拷贝构造函数和 []、=、+、== 、!=、<< 、>> 运算符重载函数。
自定义MyString估计是C++岗位常考的题目吧,能够较好的验证面试者对C++基础知识掌握的是否牢固。值得每个C++程序员注意的时,如果参数有传递引用,一定要有非空验证,因为引用帮我们封装了指针,MyString *pStr = nullptr; 将*pstr传递给引用参数是不会报错的,但是程序运行会崩溃的!
下面是笔者的写法。
MyString.h
#pragma once
#include <cstdlib>
#include <iostream>
using namespace std;
class MyString
{
public:
MyString(const char* pData = nullptr);
MyString(const MyString& otherStr);
~MyString();
MyString& operator=(const MyString& otherStr);
MyString& operator=(const char* pData);
char& operator[](unsigned int index);
MyString operator+(const MyString &str);
MyString operator+(const char* pData);
bool operator==(const MyString &str);
bool operator==(const char* pData);
bool operator!=(const MyString &str);
bool operator!=(const char* pData);
friend ostream& operator<<(ostream& cout, const MyString& str);
friend istream& operator>>(istream& cin, MyString& str);
private:
char* m_pData;
int m_size;
int m_capacity;
};
ostream& operator<<(ostream& cout, const MyString& str);
istream & operator >> (istream & cin, MyString & str);
MyString.cpp
#include "01MyString.h"
/* 普通构造函数 */
MyString::MyString(const char * pData)
{
if (nullptr == pData)
{
m_size = 0;
m_capacity = 100;
m_pData = new char[m_capacity]{ 0 };
return;
}
m_size = strlen(pData);
m_capacity = 2 * m_size + 1; //开辟2倍大空间,方便后续存储
m_pData = new char[m_capacity]{ 0 };
strcpy(m_pData, pData);
}
/* 拷贝构造函数 */
MyString::MyString(const MyString & otherStr)
{
if (nullptr == &otherStr) //参数传递引用时一定要做非空验证
{
m_size = 0;
m_capacity = 100;
m_pData = new char[m_capacity] { 0 };
return;
}
m_size = otherStr.m_size;
m_capacity = otherStr.m_capacity;
m_pData = new char[m_capacity]{ 0 };
strcpy(m_pData, otherStr.m_pData);
}
/* 析构函数 */
MyString::~MyString()
{
if(nullptr != m_pData)
delete[] m_pData;
}
MyString & MyString::operator=(const MyString & otherStr)
{
if (this != &otherStr) //剑指offer写法
{
MyString tmpStr(otherStr); //调用拷贝构造,交换字符串指针
char* p = tmpStr.m_pData;
tmpStr.m_pData = m_pData;
m_pData = p;
}
return *this;
}
MyString & MyString::operator=(const char * pData)
{
MyString tmpStr(pData); //调用构造函数
char* p = tmpStr.m_pData;
tmpStr.m_pData = m_pData;
m_pData = p;
return *this;
}
/* 返回新对象 */
MyString MyString::operator+(const MyString & str)
{
if (nullptr == &str)
{
return MyString(*this);
}
int newSize = m_size + str.m_size + 1;
char* temp = new char[newSize] {0};
strcat(temp, m_pData);
strcat(temp, str.m_pData);
MyString res(temp);
delete[] temp;
return res;
}
/* 返回新对象 */
MyString MyString::operator+(const char * pData)
{
if (nullptr == pData)
{
return MyString(pData);
}
int newSize = m_size + strlen(pData) + 1;
char* temp = new char[newSize] {0};
strcat(temp, m_pData);
strcat(temp, pData);
MyString res(temp);
delete[] temp;
return res;
}
char & MyString::operator[](unsigned int index)
{
return m_pData[index];
}
bool MyString::operator==(const MyString & str)
{
bool res = false;
if (nullptr == &str)
res = false;
if (this == &str)
res = true;
if (strcmp(m_pData, str.m_pData) == 0)
res = true;
return res;
}
bool MyString::operator==(const char * pData)
{
bool res = false;
if (nullptr == pData)
res = false;
if (strcmp(m_pData, pData) == 0)
res = true;
return res;
}
bool MyString::operator!=(const MyString & str)
{
return !operator==(str);
}
bool MyString::operator!=(const char * pData)
{
return !operator==(pData);
}
ostream& operator<<(ostream& cout, const MyString& str)
{
if (nullptr == &str)
return cout;
cout << str.m_pData;
return cout;
}
inline istream & operator >> (istream & cin, MyString & str)
{
if (nullptr == &str)
return cin;
memset(str.m_pData, 0, str.m_capacity); //清空数据
cin >> str.m_pData;
return cin;
}
int main(int argc, char *argv[])
{
//测试 构造函数 拷贝构造函数
MyString name = "Laymond";
MyString copyName = name;
cout << name << " " << copyName << endl;
//测试 [] 运算符
copyName[0] = 'A';
cout << copyName << endl;
//测试 + = 运算符
copyName = name + " is " + "good !";
cout << copyName << endl;
//测试<< >> == != 运算符
MyString str1, str2;
cin >> str1 >> str2;
cout << "str1:"<<str1 << endl;
cout << "str2:"<<str2 << endl;
cout << (MyString("hello") == "hello") << endl;
cout << (MyString("hello") != MyString("hello")) << endl;
cout << (MyString("hello") == MyString("hello")) << endl;
//在参数中引用的地方,一定要做非空验证,比如说如下,如果拷贝构造函数 没有做非空验证 程序会崩溃
MyString *pStr = NULL;
MyString str(*pStr);
return 0;
}