一、答案
#include <iostream>
#include <string.h>
#include <assert.h>
class String
{
public:
String(const char *str = nullptr);
String(const String &other);
~String(void);
String &operator=(const String &other);
bool operator==(const String &str);
char *Stringcpy(char *dst, const char *src);
friend std::ostream &operator<<(std::ostream &o, const String &str);
private:
char *m_data;
};
String::String(const char *str)
{
if (str == nullptr)
{
m_data = new char[1];
*m_data = '\0';
}
else
{
int len = strlen(str);
m_data = new char[len + 1];
Stringcpy(m_data, str);
}
}
String::~String(void)
{
delete[] m_data;
}
String::String(const String &other)
{
int len = strlen(other.m_data);
m_data = new char[len + 1];
Stringcpy(m_data, other.m_data);
}
char *String::Stringcpy(char *dst, const char *src)
{
assert(dst != nullptr);
assert(src != nullptr);
char *ret = dst;
while ((*dst++ = *src++) != '\0')
;
return ret;
}
String &String::operator=(const String &other)
{
if (this == &other)
return *this;
String tmp(other);
char *p = tmp.m_data;
tmp.m_data = m_data;
m_data = p;
return *this;
}
bool String::operator==(const String &str)
{
return strcmp(m_data, str.m_data) == 0;
}
std::ostream &operator<<(std::ostream &o, const String &str)
{
o << str.m_data;
return o;
}
int main()
{
String s = "hello";
String s2 = s;
String ss = "hello";
std::cout << "s = " << s << std::endl;
std::cout << "s2 = " << s2 << std::endl;
std::cout << std::boolalpha << (ss == s) << std::endl;
return 0;
}
二、其他
这里面有个考点,就是赋值构造函数的写法。传统的写法可能如下:
String &String::operator=(const String &other)
{
if (this == &other)
return *this;
delete[] m_data;
int len = strlen(other.m_data);
m_data = new char[len + 1];
Stringcpy(m_data, other.m_data);
return *this;
}
这种写法能够很好的完成功能,但是问题在于如果 new char 时如果系统内容不足的话就会抛出异常,此时因为上一句代码已经将 m_data 释放掉了,所以此时的 String 实例就是异常的。就算外面已经做好异常处理,String 实例已经是不能再用的了。
解决这个问题的方案可以是将 new char 放置到 delete 的前面,这样就算抛出了异常也不会造成 String 实例的异常。
另外一种方案就是上面答案中的方法,巧妙的是不仅可以解决上述问题,还可以通过临时变量退出当前上下文时自动释放内存的方式释放掉之前的字符串。
参考:https://blog.csdn.net/qq_31558353/article/details/50788843
(SAW:Game Over!)