-
历史遗留问题
— 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语言中的字符串函数实现