• 二十一、字符串类的创建


    1、C语言存在的问题

    • C语言不支持真正意义上的字符串
    • C语言用字符数组和一组函数实现字符串操作
    • C语言不支持自定义类型,无法获得字符串类型

    C++可以通过类完成字符串类型的定义,但是原生类型系统并没有包含字符串类型,而是在STL库中。

    但是不同的应用中,可能会使用不同的库。

    2、字符串类的设计

    String类继承自顶层父类Object,具体实现时依赖于C语言关于字符串函数的一个包,即关于字符串的函数集。

    class String : public Object
    {
    protected:
        char* m_str;    // 指向字符串,字符串的具体表现形式就是字符数组
        int m_length;
    
        void init(const char *s);
    
      public:
        String();
        String(const char *s);
        String(const String &s);
        int length() const;
        const char *str() const;
    
        // 比较操作符重载函数
        // 加法操作符重载函数
        // 赋值操作符重载函数
        
        ~String() { }
    };
    

    字符串类创建的注意事项:

    • 无缝实现String对象与char* 字符串的互操作
    • 操作符重载函数要考虑是否支持const版本
    • 通过C语言中的字符串函数实现String的成员函数

    本质:使用面向对象的技术,对C语言中相关字符串函数进行封装

    目标:高效地实现代码复用

    3、字符串的具体实现

    // DTString.h
    #ifndef STRING_H
    #define STRING_H
    
    #include "Object.h"
    
    namespace DTLib
    {
    
    class String : public Object
    {
    protected:
      char *m_str; // 指向字符串,字符串的具体表现形式就是字符数组
      int m_length;
    
      void init(const char *s); // 初始化函数
    
    public:
      String();
      String(char c);
      String(const char *s);
      String(const String &s);
      int length() const;
      const char *str() const;
    
      // 比较操作符重载函数
      bool operator==(const String &s) const;
      bool operator==(const char *s) const; // 针对char*
    
      bool operator!=(const String &s) const;
      bool operator!=(const char *s) const; // 针对char*
    
      bool operator>(const String &s) const;
      bool operator>(const char *s) const; // 针对char*
    
      bool operator<(const String &s) const;
      bool operator<(const char *s) const; // 针对char*
    
      bool operator>=(const String &s) const;
      bool operator>=(const char *s) const; // 针对char*
    
      bool operator<=(const String &s) const;
      bool operator<=(const char *s) const; // 针对char*
      // 加法操作符重载函数
    
      String operator+(const String &s);
      String operator+(const char *s);
      String operator+=(const String &s);
      String operator+=(const char *s);
    
      // 赋值操作符重载函数 3种
      String operator=(const String &s);
      String operator=(const char *s);
      String operator=(char c);
    
      ~String();
    };
    
    } // namespace DTLib
    
    #endif // !STRING_H
    
    
    // DTString.cpp
    
    #include <cstring>
    #include <cstdlib>
    #include "DTString.h"
    #include "Exception.h"
    
    using namespace std;
    
    namespace DTLib
    {
    
    // 使用参数s来具体产生当前字符串对象中的数据
    void String::init(const char *s) // 初始化函数
    {
        m_str = strdup(s); // 将s复制一份出来
        if (m_str)
        { // 复制成功
            m_length = strlen(m_str);
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "No memory to creat String Object...");
        }
    }
    String::String()
    {
        init("");
    }
    
    String::String(const char c)
    {
        // 字符数组模拟字符串
        // 构造字符串
        char s[] = {c, ''};
        init(s);
    }
    String::String(const char *s)
    {
        // 防止s是空指针,空指针转换成空字符串
        init(s ? s : "");
    }
    String::String(const String &s)
    {
        init(s.m_str);
    }
    
    int String::length() const
    {
        return m_length;
    }
    const char *String::str() const
    {
        return m_str; // 直接返回成员指针
    }
    
    bool String::operator==(const String &s) const
    {
        return (strcmp(m_str, s.m_str) == 0);
    }
    bool String::operator==(const char *s) const // 针对char*
    {
        return (strcmp(m_str, s ? s : "") == 0);
    }
    
    bool String::operator!=(const String &s) const
    {
        return !(*this == s);
    }
    bool String::operator!=(const char *s) const // 针对char*
    {
        return !(*this == s);
    }
    
    bool String::operator>(const String &s) const
    {
        return (strcmp(m_str, s.m_str) > 0);
    }
    bool String::operator>(const char *s) const // 针对char*
    {
        return (strcmp(m_str, s ? s : "") > 0);
    }
    
    bool String::operator<(const String &s) const
    {
        return (strcmp(m_str, s.m_str) < 0);
    }
    bool String::operator<(const char *s) const // 针对char*
    {
        return (strcmp(m_str, s ? s : "") < 0);
    }
    
    bool String::operator>=(const String &s) const
    {
        return (strcmp(m_str, s.m_str) >= 0);
    }
    bool String::operator>=(const char *s) const // 针对char*
    {
        return (strcmp(m_str, s ? s : "") >= 0);
    }
    
    bool String::operator<=(const String &s) const
    {
        return (strcmp(m_str, s.m_str) <= 0);
    }
    bool String::operator<=(const char *s) const // 针对char*
    {
        return (strcmp(m_str, s ? s : "") <= 0);
    }
    
    // 加法
    String String::operator+(const String &s)
    {
        return (*this + s.m_str);
    }
    
    String String::operator+(const char *s)
    {
        String ret;
        int len = m_length + strlen(s ? s : "");
    
        char *str = reinterpret_cast<char *>(malloc(len + 1));
        if (str)
        {
            // 调用字符串相关函数
            strcpy(str, m_str);
            strcat(str, s ? s : "");
            // str保存拼接后的结果
            free(ret.m_str);
            ret.m_str = str;
            ret.m_length = len;
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "No memory to add String values...");
        }
    
        return ret;
    }
    
    String String::operator+=(const String &s)
    {
        return (*this = *this + s.m_str);
    }
    
    String String::operator+=(const char *s)
    {
        return (*this = *this + s);
    }
    
    // 重载赋值操作符
    String String::operator=(const String &s)
    {
        return (*this = s.m_str);
    }
    
    String String::operator=(const char *s)
    {
        if (m_str != s)
        {
            char *str = strdup(s ? s : "");
            if (str)
            {
                free(m_str);
                m_str = str;
                m_length = strlen(str);
            }
            else
            {
                THROW_EXCEPTION(NoEnoughMemoryException, "No memory to assign new String value...");
            }
        }
        return *this;
    }
    
    String String::operator=(char c)
    {
        char s[] = {c, ''};
        return (*this = s);
    }
    
    String::~String()
    {
        free(m_str);
    }
    
    } // namespace DTLib
    
    

    4、小结

    C/C++语言本身不支持字符串类类型

    C语言通过字符数组和一组函数支持字符串操作

    C++通过自定义字符串类型支持字符串操作

    字符串类型通过C语言中的字符串函数实现

  • 相关阅读:
    Oracle:SQL语句--对表的操作——修改列的数据类型( 即 修改字段的数据类型)
    Oracle:SQL语句--对表的操作——修改列的数据类型( 即 修改字段的数据类型)
    有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和
    有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和
    鸡兔同笼:笼子里一共有鸡和兔子35只,一共有94条退, 笼子里一共有鸡和兔子共多少只
    jQuery,使用on代替delegate,live 写法区别
    安卓手机微信页面position: fixed位置错误
    表单提交是ajax提交,PC提交没问题但是手机提交就会一直跳到error,并且也没状态码一直是0
    新版本的jquery checkbox 全选反选代码只能执行一遍,第二次就失败attr与prop区别
    倒计时js代码
  • 原文地址:https://www.cnblogs.com/chenke1731/p/9705487.html
Copyright © 2020-2023  润新知