c++ string 类 实现

下面的代码是参考网络上流传的代码加上自己的修改和添加补全而来

//string.h #include "iostream" #include<String.h> #define NULL 0 using namespace std; class String { public: String (); //无参构造函数 String ( char* ptr); //参数为char*的构造函数,默认参数为空 String (const String& OtherString); //拷贝构造函数 public: String & operator=(const String& OtherString);//赋值函数 String & operator+=(String& str); String & operator+=(char* ptr); //不能返回局部变量的引用,所以不能返回String&。 String operator+(String& RightString); //+操作 重载 String operator+(char* ptr); //+操作 重载 可强制转换char*到String bool operator>(String& RightString); //>操作 重载 bool operator<( String& RightString); //<操作 重载 bool operator==(String& RightString); //==操作 重载 const char& operator[](int index); //下标操作 重载 public: operator char *() ; public: friend ostream & String::operator<<(ostream& os,String& str) //输出流重载 { os<<str.m_data; return os; } friend istream & String::operator>>(istream& is,String& str) //输入流重载 { is>>str.m_data; return is; } public: void Insert(int index,char ch); bool Delete(int index,int count); void MakeReverse(); void TrimLeft(); void TrimRight(); void MakeUpper(); void MakeLower(); bool Empty(); bool isEmpty(); int GetLength(); //得到长度 public: ~String(); //析构函数 private: char* m_data; //成员变量 };

 

//string.cpp #include "String.h" String::String() { m_data= new char[1]; *m_data='/0'; } String::String( char* ptr ) { if(ptr==NULL) { m_data= new char[1]; *m_data='/0'; } else { int length=strlen(ptr); m_data= new char[length+1]; strcpy(m_data,ptr); } } String::String(const String& OtherString) { int length = strlen(OtherString.m_data); m_data = new char[length+1]; strcpy(m_data,OtherString.m_data); } String &String::operator=(const String &OtherString) { if(&OtherString==this) return *this; delete [] m_data; int length = strlen(OtherString.m_data); m_data = new char[length+1]; strcpy(m_data,OtherString.m_data); return *this; } String& String::operator+=(String& str) { int len1=strlen(m_data); int len2=strlen(str.m_data); char* temp=new char[len1+1]; strcpy(temp,m_data); delete [] m_data; m_data=new char[len1+len2+1]; strcpy(m_data,temp); strcat(m_data,str.m_data); delete [] temp; return *this; } String& String::operator+=(char* ptr) { int len1=strlen(this->m_data); int len2=strlen(ptr); char*temp=new char[len1+1]; strcpy(temp,this->m_data); delete [] this->m_data; this->m_data=new char[len1+len2+1]; strcpy(this->m_data,temp); strcat(this->m_data,ptr); delete [] temp; return *this; } String String::operator+(String& RightString) { if(!RightString.m_data) return *this; else if(!m_data) return RightString; else { int len1=strlen(this->m_data); int len2=strlen(RightString.m_data); //String str(temp); String str(new char[len1+len2+1]); //str.m_data=new char[len1+len2+1]; strcpy(str.m_data,this->m_data); strcat(str.m_data,RightString.m_data); return str; } } String String::operator+(char* ptr) { if(ptr==NULL) return *this; else if(!m_data) return ptr; else { int len1=strlen(this->m_data); int len2=strlen(ptr); String str(new char[len1+len2+1]); strcpy(str.m_data,this->m_data); strcat(str.m_data,ptr); return str; } } bool String::operator>(String& RightString) //>操作 重载 { return (strcmp(this->m_data,RightString.m_data)>0); } bool String::operator<( String& RightString) //<操作 重载 { return (strcmp(this->m_data,RightString.m_data)<0); } bool String::operator==(String& RightString) //==操作 重载 { return (strcmp(this->m_data,RightString.m_data)==0); } const char& String::operator[](int index) { return *(m_data+index); } String::operator char*() { return this->m_data; } int String::GetLength() { return strlen(this->m_data); } bool String::isEmpty() { return(this->GetLength()==0); } bool String::Empty() { delete [] m_data; m_data= new char[1]; *m_data='/0'; return this->isEmpty(); } void String::MakeUpper() { int len=this->GetLength(); for(int i=0;i<len;i++) { if('a'<=m_data[i]&&m_data[i]<='z') m_data[i]-=32; } } void String::MakeLower() { int len=this->GetLength(); for(int i=0;i<len;i++) { if('A'<=m_data[i]&&m_data[i]<='Z') m_data[i]+=32; } } void String::TrimLeft() { char*p=m_data; while(*m_data==' ') m_data++; char*temp=new char[strlen(m_data)+1]; strcpy(temp,m_data); //调试状态下 操作系统用DebugWin32Heap来代替正常的heap分配内存空间, //下面语句报错原因是因为delete 访问了“非法内存”,为什么呢? //因为m_data指向的区域被我们在前面m_data++中改掉了,所以前面需要 //定义指针p保存m_data原始地址 // delete [] m_data; //调试出错 delete [] p; m_data=new char[strlen(temp)+1]; strcpy(m_data,temp); delete [] temp; } void String::TrimRight() { /* //若*this对象前面含有空格,则会出问题 int len=0; char*p=m_data; while(*p++!=' ') len++; char*temp=new char[len+1]; p=m_data; while(*p!=' ') *(temp++)=*(p++); *temp='/0'; temp-=len; //strcpy(temp,m_data); // *(temp+len+1)='/0'; delete [] m_data; m_data=new char[len+1]; strcpy(m_data,temp); delete [] temp; */ int len=0; char*p=m_data; while(*p++==' ') //计算前导空格个数 len++; p--; //回退一个单位, while(*p++!=' ') //计算中间非空格个数 len++; char*temp=new char[len+1]; p=m_data; while(*p==' ') *(temp++)=*(p++); // p--; //指针移动不在while的条件()里面,所以不需要移回一个单位 // temp--; while(*p!=' ') //若字符串有前导空格,则先赋值到临时变量temp中 *temp++=*p++; *temp='/0'; temp-=len; //temp指向起始位置 //strcpy(temp,m_data); // *(temp+len+1)='/0'; delete [] m_data; //释放动态内存,代码的复杂性正在于此 m_data=new char[len+1]; strcpy(m_data,temp); delete [] temp; } void String::MakeReverse() { char* phead=m_data; char* ptail=m_data; while(*ptail!='/0') //使p指向字符串尾 ptail++; ptail--; char temp; /* while(ptail!=phead) // 若字符串长度是双数,到中间交错开了,造成访问越界.修改如下 { temp=*ptail; *ptail=*phead; *phead=temp; ptail--; phead++; }*/ int len=strlen(m_data)/2; while(len!=0) { temp=*ptail; *ptail=*phead; *phead=temp; ptail--; phead++; len--; } } void String::Insert(int index,char ch) { int len=strlen(m_data); if(index<=0||index>len+1) return; char* temp=new char[len+2]; strcpy(temp,m_data); char* ptemp=temp; ptemp+=(len+1); while(ptemp!=(temp+index-1)) { *ptemp=*(ptemp-1); ptemp--; } *ptemp=ch; delete [] m_data; m_data= new char[len+2]; strcpy(m_data,temp); delete [] temp; } bool String::Delete(int index ,int count) { int len=strlen(m_data); if(index<=0||index>len||(index+count)>len+1) return 0 ; char* temp=new char[len+1]; strcpy(temp,m_data); char* ptemp=temp; ptemp+=(index-1); while(*ptemp!='/0') { *ptemp=*(ptemp+count); ptemp++; } *ptemp='/0'; delete [] m_data; m_data= new char[len+1-count]; strcpy(m_data,temp); delete [] temp; return 1; } String::~String() { delete []m_data; } int main() { String str0; //测试无参构造函数 String str1("1111"); //测试参数为char*的构造函数 String str="0000"; String str2="2222"; String str3="0123456789"; String str4=str1; //测试拷贝构造函数 String str5="5555"; str+=str2; //测试+=操作 str+="abc"; str=str2+"efg"; str=str1+str2; //测试+操作 char* pc=( char*)str; //测试(char*)强制转换操作 cout<<str0<<endl; cout<<pc<<endl; cout<<str<<endl; cout<<str1<<endl; cout<<str2<<endl; cout<<str4<<endl; cout<<str.GetLength()<<endl; //测试Getlength函数 cout<<str3[4]<<endl; cout<<(str1==str5)<<endl; //测试等于操作 cout<<str0.isEmpty()<<endl; //测试IsEmpty函数 str1.Empty(); cout<<str1<<endl; String str6="ab3cd"; str6.MakeUpper(); // 测试MakeUpper()函数 cout<<str6<<endl; str6.MakeLower(); // 测试MakeLower()函数 cout<<str6<<endl; String str7=" leftkongge"; str7.TrimLeft(); cout<<str7<<"+end"<<endl ; String str8=" rightkongge "; str8.TrimRight(); //测试TrimLeft()函数 str8.TrimLeft(); //测试TrimRight()函数 cout<<str8<<"+end"<<endl;; String str9="abcdefghij k"; str9.MakeReverse(); //测试MakeReverse函数 cout<<str9<<endl; String str10="kondyuang"; str10.Insert(6,'k'); //测试insert()函数 cout<<str10<<endl; String str11="kondykuangj"; str11.Delete(6,6); //测试Delete()函数 cout<<str11<<endl; return 0; }

 

 

 

 在编写过程中遇到很多疑问,我不知道在相关操作函数里面 是否需要 并且有必要先 delete 【】m_data;

然后再m_data=new char【len】;如果有必要,那么频繁的释放 分配 内存是否会带来效率问题?

 如果不这样是否会有内容泄露? 到底怎么样权衡呢?望高人指点

你可能感兴趣的:(c++ string 类 实现)