代码分析c++中string类
一:回顾
(1)c++中的string类是在面试中和笔试中经常考的题目;工程代码免费下载string类的自行实现
(2)c++中的string类和fstream类合起来是处理外部数据的利器;
(3)string类经常用到findfind_first_offind_first_not_offind_last_offind_last_not_ofsubstrreplace等,以及联合使用来达到java中的split和trim
(4)使用friend仅仅是在类中进行声明的非内部却可以访问内部成员的外部函数,而且在外部不再需要friend关键字;它与成员函数的区别是,friend和外部函数不含有this对象指针;本文用到了const定义的全局最大值最小值变量(代替#define)
(5)有些函数返回的是MyString&、Char&等(引用),MyString、Char等(传值)这得看你返回的对象是函数的局部变量还是全局变量(或者类当前对象成员变量);前者只能返回一个MyString、Char等;后者强烈建议返回MyString&、Char&等(引用);
(6)有些函数的参数是constMyString&,有些是MyString&(引用);这是为什么?前者是把外部值传提到子函数内部,且不允许改变;后者是作为函数的返回值传递进去的,返回的结果为函数的处理结果(而不用函数自身返回值了)。
二:下面是简单的实现了一下string类,参照的是STL源码,但是自己理解的还是不够深,难免有一些错误,请各位指教
(1)MyString.h文件
#ifndefMYSTRING_H #defineMYSTRING_H #include"MyExcept.h" #include#include constintINI_MAX=0x7fffffff;//2^32npos constintINI_MIN=0x80000000;//-2^32 constintnpos=0xffffffff;//npos usingnamespacestd; classMyString { public: //constructor MyString();// MyString(constMyString&);// MyString(constchar*); MyString(constsize_t,constchar); //destructor ~MyString(); //attributes size_tlength();//字符串长度 boolisEmpty();//返回字符串是否为空 constchar*c_str();//返回c风格的trr的指针 //friendfuns //readwriteroperations friendostream&operator<<(ostream&,constMyString&); friendistream&operator>>(istream&,MyString&); //addoperation friendMyStringoperator+(constMyString&,constMyString&); //compareoperations friendbooloperator==(constMyString&,constMyString&); friendbooloperator!=(constMyString&,constMyString&); friendbooloperator<(constMyString&,constMyString&); friendbooloperator<=(constMyString&,constMyString&); friendbooloperator>(constMyString&,constMyString&); friendbooloperator>=(constMyString&,constMyString&); //成员函数实现运算符重载,其实一般需要返回自身对象的,成员函数运算符重载会好一些 //indexoperation char&operator[](constsize_t); constchar&operator[](constsize_t)const; //= MyString&operator=(constMyString&); //+= MyString&operator+=(constMyString&); //+= //MyStringoperator+=(constMyString&);cannotbeoverloaded //成员操作函数 //substr MyStringsubstr(size_tpos,constsize_tn); //append MyString&append(constMyString&); //insert MyString&insert(size_t,constMyString&); //assign替换 MyString&assign(MyString&,size_t,size_t); //erase删除 MyString&erase(size_t,size_t); //find_first_of查找某一个字符size_t是非符号数的,重载 //查找在字符串中第一个与str中的某个字符匹配的字符,返回它的位置。 //搜索从index开始,如果没找到就返回string::npos intfind_first_of(constchar*str,size_tindex=0); intfind_first_of(constcharch,size_tindex=0); intfind_first_of(constMyString&,size_tindex=0); //在字符串中查找第一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始。如果没找到就返回string::nops intfind_first_not_of(constchar*str,size_tindex=0); intfind_first_not_of(constcharch,size_tindex=0); intfind_first_not_of(constMyString&,size_tindex=0); //swap voidswap(MyString&lhs,MyString&rhs); //replace_all MyString&replace_all(constcharoldc,constcharnewc=NULL); MyString&replace(size_tindex,size_tnum1,size_tnum2,constcharch); //find intfind(constchar*str,size_tindex=0); intfind(constMyString&str,size_tindex=0); intfind(constcharch,size_tindex=0); //private private: char*p_str; size_tstrLength; }; #endif//MYSTRING_H
(2)MyString.cpp文件
#include"MyString.h" #include//constructor MyString::MyString():p_str(NULL),strLength(0){} MyString::MyString(constMyString&str)// { if(NULL==str.p_str) { return; } strLength=str.strLength; p_str=newchar[strLength+1]; strcpy(p_str,str.p_str); } MyString::MyString(constchar*str) { if(NULL==str) { return; } strLength=strlen(str); p_str=newchar[strLength+1]; strcpy(p_str,str); } MyString::MyString(constsize_tlen,constcharch) { if(NULL==ch) { return; } strLength=len; p_str=newchar[strLength+1]; for(size_ti=0;i >(istream&in,MyString&str) { chartmp[100];//临时字符串 if(in>>tmp) { delete[]str.p_str; str.strLength=strlen(tmp); str.p_str=newchar[str.strLength+1]; strcpy(str.p_str,tmp); } returnin; } //+加 MyStringoperator+(constMyString&lhs,constMyString&rhs) { MyStringret; ret.strLength=lhs.strLength+rhs.strLength; ret.p_str=newchar[ret.strLength+1]; strcpy(ret.p_str,lhs.p_str); strcat(ret.p_str,rhs.p_str); returnret; } //compareoperations booloperator==(constMyString&lhs,constMyString&rhs) { returnstrcmp(lhs.p_str,rhs.p_str)==0?true:false; } booloperator!=(constMyString&lhs,constMyString&rhs) { returnstrcmp(lhs.p_str,rhs.p_str)!=0?true:false; } booloperator<(constMyString&lhs,constMyString&rhs) { returnstrcmp(lhs.p_str,rhs.p_str)<0?true:false; } booloperator<=(constMyString&lhs,constMyString&rhs) { returnstrcmp(lhs.p_str,rhs.p_str)<=0?true:false; } booloperator>(constMyString&lhs,constMyString&rhs) { returnstrcmp(lhs.p_str,rhs.p_str)>0?true:false; } booloperator>=(constMyString&lhs,constMyString&rhs) { returnstrcmp(lhs.p_str,rhs.p_str)>=0?true:false; } //成员函数实现运算符重载 //indexoperation char&MyString::operator[](constsize_tindex) { if(index<0||index>=strLength) { throwOutofbond(); } returnp_str[index]; } constchar&MyString::operator[](constsize_tindex)const { if(index<0||index>=strLength) { throwOutofbond(); } returnp_str[index]; } //=赋值构造函数(判断是否是自身)为什么要这样删除呢? MyString&MyString::operator=(constMyString&other) { if(this!=&other) { if(strLength =strLength) { throwOutofbond(); } MyStringret; ret.strLength=n; //ret.p_str=newchar[n+1]; ret.p_str=newchar[ret.strLength+1];//也可以 for(size_ti=0;i =strLength) { throwOutofbond(); } char*p_old=p_str; strLength+=other.strLength; p_str=newchar[strLength+1]; for(size_ti=0;i =strLength) //{ //throwOutofbond(); //} assert(pos>0&&pos strLength) //{ //throwOutofbond(); //} //size_tindex=pos+n; //while(*(p_str+index)!='\0') //{ //*(p_str+index-n)=*(p_str+index); //++index; //} //*(p_str+index-n)='\0'; //return*this; //} //erase删除从pos开始的n个字符 MyString&MyString::erase(size_tpos,size_tn) { if((pos+n)>strLength) { throwOutofbond(); } char*p_old=p_str; strLength-=n; p_str=newchar[strLength+1]; for(size_ti=0;i =strLength) returnnpos; inttmp_len=strlen(str),j; size_tflag,min_index=INI_MAX; for(j=0;j =strLength) returnnpos; intj; size_tflag=npos; for(size_ti=index;i =strLength) returnnpos; intj; size_tflag,min_index=INI_MAX; for(j=0;j =strLength) returnnpos; size_ti=0,j=0; size_ttmp_len=strlen(str); for(i=index;i =strLength) returnnpos; size_ti=0,j=0; for(i=index;i =strLength) returnnpos; size_ti=0; for(i=index;i (3)测试函数main.cpp
#include"MyString.h" #includeusingnamespacestd; intmain() { intn; intchoose=1; intp,l; charcs[100]; MyStrings1; MyStrings2("hello"); MyStrings3="HELLO"; cout<<"*****welcome*****\n"; cout<<"*******MADEBYzyp**********\n"; cout<<"s1="< >s1; s1=s1; //s1=s1+s1; s1+=s1; MyStrings4(s1); s4.append(s1); s2.insert(2,s3); s1.erase(4,4); s1.assign(s2,1,7); cout<<"s1="< =s2)<<"s4.substr()"< 三:感悟
(1)耗时将近2天的实现了它,自己与其从中学到了很多,倒不如说是重新认识了string类;
(2)自己知道这个简单的string类,距离string源代码还差的很远很远;但是它帮助我更好的理解了string类,至少会简单的应用了。
(3)简单的实现了一下string类,参照的是STL源码,但是自己理解的还是不够深,难免有一些错误,请各位指教,万分感谢!
(4)下一步进军list