一. 环境
Linux x86_64,g++ 8.5.0
二. 实现
自实现 string 之前一直想写来着,一直拖着,现在把它完稿。这个版本是比较简单的版本,有一些可能有不同的或者更好的实现方式,后面有机会会加到里面。
打算实现的接口如下- class MyString
- {
- friend std::ostream & operator<<(std::ostream & co, const MyString &ms);
- friend std::istream & operator>>(std::istream & ci, MyString &ms);
- public:
- MyString(const char * s = nullptr);
- ~MyString();
- MyString(const MyString & another);
- MyString & operator=(const MyString & another);
- MyString operator+(const MyString & another);
- MyString & operator+=(const MyString & another);
- bool operator>(const MyString & another);
- bool operator<(const MyString & another);
- bool operator==(const MyString & another);
- char & operator[](int n);
- char & at(int n);
- private:
- char * m_str;
- };
复制代码
- 重载 + 运算符,成员函数返回一个临时对象。在申请新的空间后,在使用 strcat() 之前需要初始化,否则可能会出现问题。strcat() 是从末尾为 '\0' 的地方开始拼接的。
- MyString::MyString(const char *str)
- {
- if (nullptr == str)
- {
- m_str = new char[1];
- *m_str = '\0';
- }
- else
- {
- m_str = new char[strlen(str)+1];
- strcpy(m_str, str);
- }
- }
复制代码
- 重载 += 运算符,返回值类型是引用类型,这样可以连续使用 +=。
使用 realloc() 后,在使用 strcat() 连接两个字符串之前,需要将 m_str 后面一部分新扩充的空间进行初始化。- // version1
- /*
- MyString & MyString::operator=(const MyString &another)
- {
- if (this == &another)
- {
- return *this;
- }
- delete []m_str;
- int len = strlen(another.m_str);
- m_str = new char[len+1];
- strcpy(m_str, another.m_str);
- return *this;
- }
- */
- // version2,采用 copy and swap 技术
- MyString & MyString::operator=(const MyString &another)
- {
- if (this == &another)
- {
- return *this;
- }
- MyString ms(another);
- std::swap(this->m_str, ms.m_str);
- return *this;
- }
复制代码- MyString MyString::operator+(const MyString &another)
- {
- MyString ms;
- int len = strlen(this->m_str) + strlen(another.m_str);
- delete []ms.m_str;
- ms.m_str = new char[len +1]{0}; // 注意初始化
- strcat(strcat(ms.m_str, this->m_str), another.m_str);
- return ms;
- }
复制代码 重载 运算符。</ol>在测试成员函数前,可以早点写这两个函数,测试时就方便打印了,不然还需要单独添加一个成员函数返回 m_str 了。
重载运算符,目标形式是:- MyString & MyString::operator+=(const MyString &another)
- {
- int lenOfSource = strlen(this->m_str);
- int lenOfAnother = strlen(another.m_str);
- this->m_str = (char *)realloc(this->m_str, lenOfSource+lenOfAnother+1);
- memset(this->m_str+lenOfSource, 0, lenOfAnother+1);
- strcat(this->m_str, another.m_str);
- return *this;
- }
复制代码 对于重载,一般会考虑到成员函数重载和全局重载,但是 ostream 类和 istream 类都是系统提供的类,我们不可能在 ostream 类和 istream 类中进行修改,因此只能放弃成员函数重载。此时,只能是全局重载,即全局函数重载了。
考虑到会连续输出(cout |