设计的效果:
自用
还可以和vector一起用
调用方法
MySTL::LiteString s;
cout << "s\n" << "IsEmpty() " << s.empty() << endl << endl;
MySTL::LiteString s2("hello world\0");
cout << "s2\n" << s2 << endl;
cout << "s2 operator[5]\t" << s2[6] << endl;
cout << "s2.front()\t" << s2.front() << endl;
cout << "s2.back()\t" << s2.back() << endl;
cout << "s2.size()\t" << s2.size() << endl << endl;
MySTL::LiteString s3 = s2;
cout << "s3\n" << s3 << endl << endl;
cout << "s2 + s3\n" << s2 + s3 << endl << endl;
MySTL::LiteString s4(s2);
cout << "s4\n" << s4 << endl;
string ss("123");
string ss2("456");
cout << (ss < ss2) << endl;
cout << (ss == ss2) << endl;
cout << (ss > ss2) << endl;
cout << (ss <= ss2) << endl;
cout << (ss >= ss2) << endl;
cout << (ss != ss2) << endl << endl;
废话不多,上代码:
【别忘了写在自己的命名空间,防止冲突】
#ifndef LITESTRING_H_INCLUDED
#define LITESTRING_H_INCLUDED
#include<assert.h>
#include<iostream>
namespace MySTL{
const char* strcpy(char* dest, const char* src);
size_t strlen(const char* p);
char* strcat(char *dest, const char* src);
int strcmp(const char* p1, const char* p2);
const char* strcpy(char* dest, const char* src){//一定要保证dest足够大
assert(dest != NULL && src != NULL);
//想要避免内存覆盖,可以借鉴memmove,copy和move
//这里来判别dest和src是否是指向同一字符串中不同位置,
//如果是指向同一字符串,但是dest在src前面,则可以从前往后逐个赋值
//如果是指向同一字符串,但是dest在src后面,且dest>=src+count,那么仍然从前往后赋值
size_t copyLen = strlen(src);
if (dest < src || dest >= src + copyLen){
char *p = dest;
while ((*p++ = *src++) != '\0');
return dest;
}
else{//如果dest < src + copyLen,则从后往前拷贝
size_t offset = copyLen - 1;
char *p = dest + offset;
src += offset;
while (p != dest){
*p-- = *src--;
}
return dest;
}
}
size_t strlen(const char* p){
size_t len = 0;
while ((*p++) != '\0'){
++len;
}
return len;
}
char* strcat(char *dest, const char* src){//默认dest的空间足够大且区域不重叠
char* p = dest;
while (*p != '\0'){
p++;
}
while ((*p++ = *src++) != '\0');
return dest;
}
int strcmp(const char* p1, const char* p2){
while (*p1 == *p2){ //不可用while(*str1++==*str2++)来比较,当不相等时仍会执行一次++,导致位数相同时仍然返回0
if (*p1 == '\0'){
return 0;
}
++p1;
++p2;
}
return *p1 - *p2;
}
class LiteString{
public:
LiteString(){
data = NULL;
length = 0;
}
LiteString(const char *p){
if (p == NULL){
data = new char[1];
*data = '\0';
length = 0;
}
else{
length = strlen(p);
data = new char[length + 1];
strcpy(data, p);
}
}
LiteString(const LiteString &oth){//深拷贝
length = strlen( oth.data);
data = new char[length + 1];
strcpy(data, oth.data);
}
LiteString(LiteString &&oth){//move语义
length = oth.length;
oth.length = 0;
data = oth.data;
oth.data = NULL;
}
size_t size(){
return length;
}
const char* c_str() const{
return data;
}
char& operator[](size_t n){
assert(n >= 0 && n < length);
return data[n];
}
LiteString operator+(const LiteString& oth){
LiteString tmp;
tmp.length = length + strlen(oth.data);
tmp.data = new char[tmp.length + 1];
strcpy(tmp.data, data);
strcat(tmp.data, oth.data);
return tmp;
}
LiteString& operator=(const LiteString& oth){
if (this == &oth){//如果就是他本身
return *this;
}
delete []data;
length = strlen(oth.data);
data = new char[length + 1];
strcpy(data, oth.data);
return *this;
}
friend std::istream& operator>>(std::istream &is, LiteString& str){
is >> str.data;
return is;
}
friend std::ostream& operator<<(std::ostream &os, LiteString& str){
os << str.data;
return os;
}
~LiteString(){
length = 0;
delete []data;
}
//front back empty均为标准String操作
const char front(){
if (length > 0){
return data[0];
}
return '\0';
}
const char back(){
if (length > 0){
return data[length - 1];
}
return '\0';
}
bool empty(){
return length == 0;
}
//关系操作符,其中 operator< 和 operator==是核心,其他的都是转调用这些
friend bool operator < (const LiteString& cur, const LiteString &oth){
return strcmp(cur.data, oth.data) < 0;
}
bool operator == (const LiteString &oth){
return strcmp(data, oth.data) == 0;
}
bool operator > (const LiteString &oth){
return (oth < *this);
}
bool operator <= (const LiteString &oth){
return !(*this > oth);
}
bool operator >= (const LiteString &oth){
return !(*this < oth);
}
bool operator != (const LiteString &oth){
return !(*this == oth);
}
private:
char *data; //一个指向 new 后内存的指针
size_t length; //数据长度
};
}
#endif // LITESTRING_H_INCLUDED