标签:复制 ring std news friend 运算 namespace 内存管理 字符串长度
用C++实现了简易版字符串类,原理还是用C语言风格的字符指针实现,主要为了练习C++的内存管理。
String有功能构造析构复制赋值和常见操作符,特别需要注意的是赋值和+=的时候相当于把原理的String的字符串抛弃掉了,这时候如果不对之前的字符串进行释放处理的话会造成内存泄漏!!
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 class String { 5 private: 6 char *ptr; //字符串首指针 7 size_t len; //字符串长度 8 9 public: 10 String(const char *str=NULL); //构造函数 11 String(const String &str); //复制构造函数 12 ~String(); //析构函数 13 14 friend String operator + (const String& str1,const String& str2); //重载加号 15 16 String& operator = (const String& str); //重载赋值运算符 17 String& operator += (const String& str); //重载+= 18 bool operator == (const String &str); //重载相等判断符 19 char& operator [] (int n); //重载下标取值 20 21 bool operator != (const String& str) const; 22 bool operator < (const String& str) const; 23 bool operator <= (const String& str) const; 24 bool operator > (const String& str) const; 25 bool operator >= (const String& str) const; 26 27 size_t size() const; //返回长度 28 const char* c_str() const; //获得String的C风格字符串 29 30 //输入输出运算 31 friend istream& operator >> (istream &is,String &str); 32 friend ostream& operator << (ostream &os,String &str); 33 }; 34 35 //字符串拷贝函数:把strSrc串拷贝到strDest串 36 char* strcpy(char *strDest,const char *strSrc) { 37 if (strDest==NULL || strSrc==NULL) return NULL; 38 if (strDest==strSrc) return strDest; 39 char *head=strDest; //先把首指针保存一份用来输出 40 while ((*strDest++ = *strSrc++) != ‘\0‘); 41 return head; 42 } 43 44 String::String(const char *str) { 45 if (str==NULL) { //构造为空串 46 this->len=0; 47 this->ptr=new char[1]; 48 *ptr=‘\0‘; 49 } else { 50 this->len=strlen(str); 51 this->ptr=new char[this->len+1]; //为什么+1,考虑‘\0‘ 52 strcpy(this->ptr,str); 53 } 54 } 55 String::String(const String &str) { 56 this->len=str.len; 57 this->ptr=new char[this->len+1]; 58 strcpy(this->ptr,str.ptr); 59 } 60 String::~String() { 61 delete []this->ptr; 62 this->len=0; 63 } 64 65 size_t String::size() const { 66 return this->len; 67 } 68 const char* String::c_str() const { 69 return this->ptr; 70 } 71 72 String operator + (const String& str1,const String& str2) { 73 String newString; 74 newString.len=str1.len+str2.len; 75 newString.ptr=new char[newString.len+1]; 76 strcpy(newString.ptr,str1.ptr); 77 strcat(newString.ptr,str2.ptr); 78 return newString; 79 } 80 String& String::operator = (const String& str) { 81 if (this==(&str)) return *this; 82 //这一步很关键,先把以前的空间删掉再赋值,否则空间泄露 83 delete []this->ptr; 84 85 this->len=str.len; 86 this->ptr=new char[this->len+1]; 87 strcpy(this->ptr,str.ptr); 88 return *this; 89 } 90 String& String::operator += (const String& str) { 91 //+=和上面的=同理,注意把以前的空间先释放 92 char *tmp=this->ptr; 93 *this=*this+str; 94 delete []tmp; 95 return *this; 96 } 97 //内联函数加快运行速度 98 inline bool String::operator == (const String& str) { 99 if (this->len!=str.len) return 0; 100 for (int i=0;i<this->len;i++) 101 if (*(this->ptr+i) != *(str.ptr+i)) return 0; 102 return 1; 103 } 104 char& String::operator [] (int n) { 105 //if (n>this->len-1) throw; //越界异常 106 return *(this->ptr+n); 107 } 108 109 bool String::operator != (const String& str) const { 110 if (this->len!=str.len) return 1; 111 for (int i=0;i<this->len;i++) 112 if (*(this->ptr+i) != *(str.ptr+i)) return 1; 113 return 0; 114 } 115 bool String::operator < (const String& str) const { 116 int minlen=min(this->len,str.len); 117 bool ret=0; int equal_point=-1; 118 for (int i=0;i<minlen;i++) 119 if (*(this->ptr+i) != *(str.ptr+i)) { 120 if (*(this->ptr+i) < *(str.ptr+i)) ret=1; 121 break; 122 } else equal_point=i; 123 if (equal_point==minlen-1 && this->len-1==equal_point && str.len-1>equal_point) ret=1; 124 return ret; 125 } 126 bool String::operator > (const String& str) const { 127 int minlen=min(this->len,str.len); 128 bool ret=0; int equal_point=-1; 129 for (int i=0;i<minlen;i++) 130 if (*(this->ptr+i) != *(str.ptr+i)) { 131 if (*(this->ptr+i) > *(str.ptr+i)) ret=1; 132 break; 133 } else equal_point=i; 134 if (equal_point==minlen-1 && this->len-1>equal_point && str.len-1==equal_point) ret=1; 135 return ret; 136 } 137 138 istream& operator >> (istream &is,String &str) { 139 char s[100]; scanf("%s",s); 140 str.len=strlen(s); 141 strcpy(str.ptr,s); 142 } 143 ostream& operator << (ostream &os,String &str) { 144 for (int i=0;i<str.len;i++) 145 os<<*(str.ptr+i); 146 return os; 147 } 148 149 int main() 150 { 151 String s1; cin>>s1; cout<<s1<<endl; 152 //这里的串会当成C语言字符串,调用构造函数 153 String s2("AqA"); cout<<s2<<endl; 154 //这里的s2就是String类了,调用复制构造函数 155 String s3(s2); cout<<s3<<endl; 156 157 String s4(s2+s1+s3); cout<<s4<<endl; 158 //这里的"11"会自动转成String ? 159 String s5=s4+"11"; cout<<s5<<endl; 160 161 cout<<s5[3]<<endl; 162 cout<<"s2==s3 ? "<<(s2==s3)<<endl; 163 cout<<"s1==s3 ? "<<(s1==s3)<<endl; 164 165 //这里测试各种比较符号 166 String s6("AAbb"); 167 String s7("AAbb"); 168 String s8("AAbba"); 169 String s9("AAbab"); 170 cout<<"s6==s7 ? "<<(s6==s7)<<endl; 171 cout<<"s6>s7 ? "<<(s6>s7)<<endl; 172 cout<<"s6<s7 ? "<<(s6<s7)<<endl; 173 cout<<"s6>s8 ? "<<(s6>s8)<<endl; 174 cout<<"s6<s8 ? "<<(s6<s8)<<endl; 175 cout<<"s8>s9 ? "<<(s8>s9)<<endl; 176 cout<<"s7>s9 ? "<<(s7>s9)<<endl; 177 return 0; 178 }
标签:复制 ring std news friend 运算 namespace 内存管理 字符串长度
原文地址:https://www.cnblogs.com/clno1/p/12806551.html