• 字符串类的创建(上)


    C语言中,其实是使用字符数组来模拟字符串的,如果一个字符数组以为结束符的话,那么这个字符数组就是C语言中合法的字符串了。一个字符数组是不是字符串的标准就是是否以来作为结束标志。

    在C语言中是找不到一个数据类型来单独描述字符串的,要么就通过字符数组,要么就通过char*指针。

    为了兼容C语言,C++在原生类型系统中还是没有包含字符串类型,那么C++中是如何支持字符串类型的呢?它是通过库实现的,比如说,与C++同时发布的stl标准库,stl中就有String这个类,该类就是官方承认的C++里面的字符串类型了。但是这么做还是有问题的,比如说在某个实际的工程开发中,也许是不能使用stl标准库的,使用的是另一种库,比如说使用的是Qt,Qt中也提供了一个字符串类型,叫做QString。还有可能使用的是MFC,它提供了CString类。也就是说,只要使用了C++中的一个库,那么库中必然会提供字符串类型出来。这就是C++世界中字符串类型了,可以说没有统一的字符串类型,都是库提供的字符串类型。

    我们现在正写一个库,因此我们也必须在DTLib中实现字符串类。所有厂商设计的字符串类的设计基本上是一样的。

     

     

     

    其实就是使用面向对象的技术,对C语言中的字符串函数进行封装。 

    字符串类的实现:String.h String.cpp

     String.h

    #ifndef DTSTRING_H
    #define DTSTRING_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; //用于进行和传统的C语言字符串函数进行互操作的函数
    
        bool operator ==(const String& s) const;
        bool operator ==(const char* s) const;
        bool operator !=(const String& s) const;
        bool operator !=(const char* s) const;
        bool operator >(const String& s) const;
        bool operator >(const char* s) const;
        bool operator <(const String& s) const;
        bool operator <(const char* s) const;
        bool operator <=(const String& s) const;
        bool operator <=(const char* s) const;
        bool operator >=(const String& s) const;
        bool operator >=(const char* s) const;
    
        String operator +(const String& s) const;
        String operator +(const char* s) const;
        String& operator +=(const String& s) ;
        String& operator +=(const char* s) ;
    
        String& operator = (const String& s);
        String& operator = (const char* s);
        String& operator = (char c);
    
        ~String();
    
    };
    
    }
    
    #endif // DTSTRING_H

    String.cpp

    #include "DTString.h"
    #include <cstring>
    #include <cstdlib>
    #include "Exception.h"
    
    
    
    namespace DTLib
    {
    
    void String::init(const char* s)
    {
        m_str = strdup(s);
        if(m_str)
        {
            m_length = strlen(m_str);
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException,"no enough memory to create string object...");
        }
    }
    
    String ::String()
    {
        init("");
    }
    
    String::String(const char* s)
    {
        init(s ? s : ""); //为了防止空指针的问题,如果是以空指针来创建一个对象,就将空指针转换成一个字符串
    }
    
    String::String(const String& s)
    {
        init(s.m_str);
    }
    
    String::String(const char c)
    {
        //以一个字符作为参数,来创建一个字符串对象。因为在C语言中是以作为字符串的结束标志
        char s[] = {c, ''};
        init(s);
    }
    
    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
    {
        return(strcmp(m_str,s ? s :" ") == 0);
    }
    
    bool String::operator !=(const String& s) const
    {
        return !(*this == s);
    }
    
    bool String::operator !=(const char* s) const
    {
        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
    {
        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
    {
        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
    {
        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
    {
        return (strcmp(m_str,s ? s : "") <= 0);
    }
    
    String String::operator +(const String& s) const
    {
        return (*this + s.m_str);
    }
    
    String String::operator +(const char* s) const
    {
        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 : "");
    
            free(ret.m_str);
            ret.m_str = str;
            ret.m_length = len;
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException,"no enough memory to allocate...");
        }
        return ret;
    }
    
    String& String::operator +=(const String& s)
    {
        return (*this = *this + s.m_str);  //在这里使用了赋值操作符,因此还需要实现赋值操作符的重载
    }
    
    String& String::operator +=(const char* s)
    {
        return (*this = *this + (s ? 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);
            if(str)
            {
                free(m_str);
                m_str = str;
                m_length = strlen(m_str);
            }
            else
            {
                THROW_EXCEPTION(NoEnoughMemoryException,"no enough memeory to create new value...");
            }
    
        }
    
        return *this;
    }
    
    String& String::operator = (char c)
    {
        char s[] = {c, ''};
        return (*this = s);
    }
    String:: ~String()
    {
        free(m_str);
    }
    
    }

    main.cpp

    #include <iostream>
    #include "DTString.h"
    
    using namespace std;
    using namespace DTLib;
    
    void test_1()
    {
        cout << "test_1 begin ..." << endl;
    
        String s;
    
        s= 'J';
    
        cout << s.str() << endl;
        cout << s.length() << endl;
        cout << (s == 'J') << endl;
        cout << (s > 'C') << endl;
    
        s += " jackson is strong ";
        cout << s.str() << endl;
        cout << s.length() << endl;
        cout << (s == "J jackson is strong ") << endl;
    
        cout << "test_1 end..." << endl;
    }
    
    void test_2()
    {
        cout << "test_2 begin ..." << endl;
    
        String a[] = {"E","D","C","B","A"};
        String min = a[0];
    
        for(int i=0; i<5; i++)
        {
            if(min > a[i])
            {
                min = a[i];
            }
        }
    
        cout << "the most smaller is " << min.str() << endl;
    
        cout << "test_2 end..." << endl;
    }
    
    int main()
    {
        test_1();
        test_2();
        return 0;
    }

     打印结果符合预期,因此实现的字符串类实现了基本的功能。

  • 相关阅读:
    QML用Qt.labs.settings实现保存用户设置
    周练1
    Django的Hello World
    python 笔记
    Qt Creator 搭配Git 版本控制
    Windows系统下在Git Bash中把文件内容复制到剪贴板的命令
    【转】Qt之JSON保存与读取
    Qt Creator 中文编译失败 怎么办
    Treap树 笔记
    【POJ1037】A decorative fence(DP)
  • 原文地址:https://www.cnblogs.com/-glb/p/13258697.html
Copyright © 2020-2023  润新知