【C/C++】【练习】自己实现String类
手撕String,面试中经常会问到,今天我们自己实现并梳理MyString类,同时加深对拷贝构造,移动构造;运算符重载的理解;
成员变量
字符串MyString类中两个成员变量
- char *的字符串m_data;
- 保存字符串大小的m_size;
构造函数和析构函数
MyString(const char* str = nullptr); //函数默认参数为nullptr
~MyString();
//如果没有默认值,即str = nullptr;m_size = 0;m_data[0] = ‘\0’;
//否则,new 指定大小的堆内存,然后将内容拷贝到m_data;
MyString::MyString(const char* str)
{
if (str == nullptr)
{
m_data = new char[1];
m_data[0] = '\0';
m_size = 0;
}
else
{
m_size = strlen(str);
m_data = new char[m_size + 1];
strcpy(m_data, str);
}
}
//释放之前分配的内存
MyString::~MyString()
{
delete[] m_data;
}
拷贝构造和拷贝赋值(深拷贝)
MyString(const MyString& str);
MyString& operator=(const MyString& str);
//分配指定大小的内存,直接使用strcpy拷贝;
//为什么不先delete ???
MyString::MyString(const MyString& str)
{
m_size = str.m_size;
m_data = new char[m_size + 1];
strcpy(m_data, str.m_data);
}
//判断是不是自己给自己赋值
//如果不是,先释放原有的堆内存,然后重新分配指定大小的内存,使用strcpy拷贝;
//返回本对象的引用;
MyString& MyString::operator=(const MyString& str)
{
if (this == &str)
return *this;
delete[] m_data;
m_size = str.m_size;
m_data = new char[m_size + 1];
strcpy(m_data, str.m_data);
return *this;
}
移动构造和移动赋值
MyString(MyString&& str);
MyString& operator=(MyString&& str);
//将当前指针m_data指向str.m_data;同时修改大小;
//让str.m_data置空;
MyString::MyString(MyString&& str)
{
m_size = str.m_size;
m_data = str.m_data;
str.m_data = nullptr;
}
//判断是不是自己移动给自己
//如果不是,先释放原有的堆内存,然后改变指针的指向;并将str.m_data置空
//返回本对象的引用;
MyString& MyString::operator=(MyString&& str)
{
if (this == &str)
return *this;
delete[] m_data;
m_size = str.m_size;
m_data = str.m_data;
str.m_data = nullptr;
return *this;
}
重载关系运算符
bool operator==(const MyString& str);
bool operator>(const MyString& str);
bool operator<(const MyString& str);
bool MyString::operator==(const MyString& str)
{
if (strcmp(m_data, str.m_data) == 0)
return true;
return false;
}
bool MyString::operator>(const MyString& str)
{
return strcmp(m_data, str.m_data) > 0;
}
bool MyString::operator<(const MyString& str)
{
return strcmp(m_data, str.m_data) < 0;
}
重载+和[]
MyString operator+(const MyString& str);
char& operator[](int idx);
MyString MyString::operator+(const MyString & str)
{
//统计长度
int len = m_size + str.m_size;
//结果字符串
MyString res;
delete []res.m_data;
//重新分配内存
res.m_data = new char[len + 1];
//先清空
memset(res.m_data, 0, len + 1);
//依次将两个字符串接在后面
strcat(res.m_data, this -> m_data);
strcat(res.m_data, str.m_data);
return res;
}
char& MyString::operator[](int idx)
{
return m_data[idx];
}
重载输入>>和输出<<
//类外部的函数,要访问MyString的私有成员,设为友元函数
friend ostream & operator<<(ostream& os, const MyString& str);
friend istream& operator>>(istream& is, MyString& str);
ostream & operator<<(ostream& os, const MyString& str)
{
os << str.m_data;
return os;
}
istream& operator>>(istream& is, MyString& str)
{
delete[] str.m_data;
char buf[1024];
scanf("%s, buf");
int len;
len = strlen(buf);
str.m_data = new char[len + 1];
strcpy(str.m_data, buf);
return is;
}
知识的价值不在于占有,而在于使用