ToB企服应用市场:ToB评测及商务社交产业平台

标题: 自实现string类 [打印本页]

作者: 万万哇    时间: 2024-1-14 03:56
标题: 自实现string类
一. 环境
Linux x86_64,g++ 8.5.0
二. 实现
自实现 string 之前一直想写来着,一直拖着,现在把它完稿。这个版本是比较简单的版本,有一些可能有不同的或者更好的实现方式,后面有机会会加到里面。
打算实现的接口如下
  1. class MyString
  2. {
  3.     friend std::ostream & operator<<(std::ostream & co, const MyString &ms);
  4.     friend std::istream & operator>>(std::istream & ci, MyString &ms);
  5. public:
  6.     MyString(const char * s = nullptr);
  7.     ~MyString();
  8.     MyString(const MyString & another);
  9.     MyString & operator=(const MyString & another);
  10.     MyString operator+(const MyString & another);
  11.     MyString & operator+=(const MyString & another);
  12.     bool operator>(const MyString & another);
  13.     bool operator<(const MyString & another);
  14.     bool operator==(const MyString & another);
  15.     char & operator[](int n);
  16.     char & at(int n);
  17. private:
  18.     char * m_str;
  19. };
复制代码
  1. MyString::MyString(const char *str)
  2. {
  3.     if (nullptr == str)
  4.     {
  5.         m_str = new char[1];
  6.         *m_str = '\0';
  7.     }
  8.     else
  9.     {
  10.         m_str = new char[strlen(str)+1];
  11.         strcpy(m_str, str);
  12.     }
  13. }
复制代码
使用 realloc() 后,在使用 strcat() 连接两个字符串之前,需要将 m_str 后面一部分新扩充的空间进行初始化。
  1. // version1
  2. /*
  3. MyString & MyString::operator=(const MyString &another)
  4. {
  5.     if (this == &another)
  6.     {
  7.         return *this;
  8.     }
  9.     delete []m_str;
  10.     int len = strlen(another.m_str);
  11.     m_str = new char[len+1];
  12.     strcpy(m_str, another.m_str);
  13.     return *this;
  14. }
  15. */
  16. // version2,采用 copy and swap 技术
  17. MyString & MyString::operator=(const MyString &another)
  18. {
  19.     if (this == &another)
  20.     {
  21.         return *this;
  22.     }
  23.     MyString ms(another);
  24.     std::swap(this->m_str, ms.m_str);
  25.     return *this;
  26. }
复制代码
  1. MyString MyString::operator+(const MyString &another)
  2. {
  3.     MyString ms;
  4.     int len = strlen(this->m_str) + strlen(another.m_str);
  5.     delete []ms.m_str;
  6.     ms.m_str = new char[len +1]{0};  // 注意初始化
  7.     strcat(strcat(ms.m_str, this->m_str), another.m_str);
  8.     return ms;
  9. }
复制代码
重载  运算符。</ol>在测试成员函数前,可以早点写这两个函数,测试时就方便打印了,不然还需要单独添加一个成员函数返回 m_str 了。
重载运算符,目标形式是:
  1. MyString & MyString::operator+=(const MyString &another)
  2. {
  3.     int lenOfSource = strlen(this->m_str);
  4.     int lenOfAnother = strlen(another.m_str);
  5.     this->m_str = (char *)realloc(this->m_str, lenOfSource+lenOfAnother+1);
  6.     memset(this->m_str+lenOfSource, 0, lenOfAnother+1);
  7.     strcat(this->m_str, another.m_str);
  8.     return *this;
  9. }
复制代码
对于重载,一般会考虑到成员函数重载和全局重载,但是 ostream 类和 istream 类都是系统提供的类,我们不可能在 ostream 类和 istream 类中进行修改,因此只能放弃成员函数重载。此时,只能是全局重载,即全局函数重载了。

考虑到会连续输出(cout




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4