C++数据结构第39课、字符串类的创建(上)

  • 历史遗留问题
    — C 语言中不支持真正意义上的字符串;
    — 它用字符数组和一组函数实现字符串操作;
    — C 语言是不支持自定义类型的,因此无法获得字符串类型。

  • 字符串类的创建
    — 从 C 到 C++ 的进化过程中引入了自定义类型,
    — 在 C++ 中可以通过类完成字符串类型的定义。
    问题:在 C++ 中的原生类型系统是否包含字符串类型呢?
    不包含,都是库提供的。所以我们写的库里面也应该包含字符串类。

  • XiebsLib 库中字符串类的设计,结构如下图所示
    在这里插入图片描述
    在这里插入图片描述

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

String 的具体实现:

XiebsString.h

#ifndef XIEBSSTRING_H
#define XIEBSSTRING_H

#include "Object.h"

namespace XiebsLib
{

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;
    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 // XIEBSSTRING_H

XiebsString.cpp

#include "XiebsString.h"
#include <cstring>
#include <cstdlib>
#include "Exception.h"
using namespace std;
namespace XiebsLib
{

void String::init(const char* s)
{
    m_str = strdup(s);

    if(m_str)
    {
        m_length = strlen(m_str);
    }
    else
    {
        THROW_EXCEPTION(NoEnoughMemoryException, "no memory to create string Object");
    }
}

String::String()
{
    init("");
}

String::String(char c)
{
    char s[] = {c, '\0'};
    init(s);
}

String::String(const char* 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
{
    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 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);         //会把末尾的 \0 拷贝过去
        strcat(str, s ? s : "");

        free(ret.m_str);

        ret.m_str = str;
        ret.m_length = len;
    }
    else
    {
        THROW_EXCEPTION(NoEnoughMemoryException, "no memory to add string value...");
    }
    return ret;
}

String String::operator +(const String& s)const
{
    return (*this + s.m_str);
}

String& String::operator +=(const char* s)
{
    return (*this = *this + s);
}

String& String::operator +=(const String& s)
{
    return (*this = *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(m_str);
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "no memory to assign new string value...");
        }
    }
    return *this;
}

String& String::operator =(const String& s)
{
    return (*this = s.m_str);
}

String& String::operator =(char c)
{
    char s[] = {c, '\0'};
    return (*this = s);
}

String::~String()
{
    free(m_str);
}
}

main.cpp

#include <iostream>
#include "XiebsString.h"

using namespace std;
using namespace XiebsLib;

void test_1()
{
    cout << "void test_1() begin..." << endl;
    String s;
    s = 'D';

    cout << s.str() << endl;
    cout << s.length() << endl;
    cout << (s == "D") << endl;
    cout << (s > "CCC") << endl;

    s += " xiebs nb ";
    cout << s.str() << endl;
    cout << s.length() << endl;
    cout << (s == "D xiebs nb ") << endl;

    cout << "void test_1() end..." << endl;
}

void test_2()
{
    cout << "void 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 << min.str() << endl;

    cout << "void test_2() end..." << endl;
}

int main()
{
    test_1();
    test_2();
    return 0;
}

在这里插入图片描述

小结:
1、C/C++语言本身不支持字符串类型
2、C语言通过字符数组和一组函数支持字符串操作
3、C++通过自定义字符串类型支持字符串操作
4、字符串类型通过C语言中的字符串函数实现

自己实现的字符串 class CMStringImp; class CMstring { public: explicit CMstring(void); ~CMstring(void); CMstring(LPCTSTR lpszstr); CMstring(const CMstring& lpszstr); CMstring& operator = (const CMstring& lpszstr); operator LPCTSTR() const; bool operator == (const CMstring&) const; bool operator != (const CMstring&) const; bool operator < (const CMstring&) const; TCHAR operator[] (int nIndex) const; TCHAR& operator[] (int nIndex); CMstring& operator += (LPCTSTR pStr); CMstring& operator += (TCHAR ch); friend CMstring operator+(const CMstring& str1, const CMstring& str2); friend CMstring operator+(const CMstring& str1, LPCTSTR lpszstr); friend CMstring operator+(const CMstring& str1, TCHAR ch); friend CMstring operator+(TCHAR ch, const CMstring& str1); friend CMstring operator+(LPCTSTR lpszstr, const CMstring& str1); // friend wostream operator <<(wostream &is;,const CMstring &str;); public: LPCTSTR GetData() const; bool IsEmpty() const; TCHAR GetAt(int) const; TCHAR& GetAt(int); int GetLength() const; int Compare(const CMstring&) const; int CompareNoCase(const CMstring&) const; int Find(TCHAR ch, int nStart = 0) const; int Find(LPCTSTR pStr, int nStart = 0) const; int ReverseFind(TCHAR ch) const; int ReverseFind(LPCTSTR pStr) const; CMstring Right(int nCount) const; CMstring Left(int nCount ) const; public: CMstring& MakeLower(); CMstring& MakeUpper(); CMstring& MakeReverse(); int Replace(TCHAR chOld, TCHAR chNew); int Replace(LPCTSTR pszOld, LPCTSTR pszNew); int Insert(int iIndex, TCHAR ch); void Format(LPCTSTR lpszFormat, ...); private: CMStringImp* m_pImp; };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值