字符串类的创建(上)

 

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

在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语言中是以\0作为字符串的结束标志
    char s[] = {c, '\0'};
    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, '\0'};
    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;
}

 

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

 

posted @ 2020-07-07 06:14  一代枭雄  阅读(321)  评论(0)    收藏  举报