Stringin C + + learning career I found that the function of the string class is very powerful, so we are very necessary to simulate the implementation of it, and in the interview when the simulation to implement a String class is also the interviewer's frequent examination, But because of the constraints of external factors we are not able to simulate the same as the string in the library (the string in C + + library is more powerful), so today we only simulate the implementation of string basic functions-constructors, copy constructors, destructors, assignment operator overloading, operator + = overload, The overloads of the operator [], C_str (get a C-style character pointer, operable string), Size,push_back,insert ( deep copy ), and the basic string class implemented in the way of write-time copy Copy_on_write deep copy of the way
Class String{friend Ostream &operator<< (ostream &os,string &s);p ublic:string (const char *str= ""); A full default constructor that resolves an empty string problem string (const string &ps); Deep copy String &operator= (string s); String &operator+= (const char * s); const char *C_STR () const//Get C-style character pointer {return _PSTR;} Char &operator[] (size_t index) {return _pstr[index];} size_t Size () Const{return _size;} void pushback (char c); String &insert (size_t pos,const char *str);//string &operator= (String &s)//{//cout<< "String & Operator= (String &s) "<<endl;//if (This! = &s)//{//delete[]_pstr;//_pstr=new char[strlen (S._PSTR) +1];/ /strcpy (_PSTR,S._PSTR);//}//return *this;//}~string () {cout<< "~string ()" <<endl;if (_pstr! = NULL) { DELETE[]_PSTR; _pstr=null; _size=0; _capacity=0;}} Private:void checkcapacity (int count);p rivate:int _size;int _capacity;char *_pstr;};o Stream &operator<< (ostream &os,string &s) {Os<<s._pstr;return os;} String::string (ConSt Char *str): _size (strlen (str)), _capacity (strlen (str) +1), _pstr (new char[_capacity]) {cout<< "String ()" < <endl;strcpy (_PSTR,STR);} string::string (const String &ps): _size (Ps._size), _capacity (strlen (PS._PSTR) +1), _pstr (new char[_capacity]) { cout<< "string (const string &ps)" <<endl;strcpy (_PSTR,PS._PSTR);} String &string::operator= (string s) {cout<< "string &operator= (String s)" <<endl;std::swap (_pstr, S._PSTR); Std::swap (_size,s._size); Std::swap (_capacity,s._capacity); return *this;} void string::checkcapacity (int count) {if (_size+count >= _capacity) {int _count= (2*_capacity) > (_capacity+count) ? (2*_capacity):(_capacity+count), char *tmp=new char[_count];strcpy (tmp,_pstr);d elete[]_pstr;_pstr=tmp;_capacity=_ Count;}} void String::P ushback (char c) {checkcapacity (1); _pstr[_size++]=c;_pstr[_size]= ';} String &string::operator+= (const char * s) {checkcapacity (strlen (s)); while (*s) {_pstr[_size++]=*s;s++;} _pstr[_size]= ' + '; return *this;} String &string::iNsert (size_t pos,const char *str) {char *tmp=new char[strlen (_pstr+pos)];strcpy (Tmp,_pstr+pos); Checkcapacity (strlen (str)); while (*STR) {_pstr[pos++]=*str;str++;} strcpy (_pstr+pos,tmp); return *this;}
by testing the above code to work, especially when implementing the assignment operator overload, we used two ways, it is worth mentioning that the swap function is used to implement the assignment operator overload (can not be referenced at the time of the argument), Since the implementation of the SWAP function is based on the creation of the temporary variable and the temporary variable is out of scope, the destructor destruction is automatically called (modern method)methods for testing deep copies
void Text1 () {String str1 ("Hello"); String str2 (STR1); String str3;str3=str1;cout<<str1<<endl;cout<<str2<<endl;cout<<str3<<endl; Cout<<strlen (str1. C_str ()) <<endl; 5str1[4]= ' W ';cout<<str1<<endl; Hellw}void Text2 () {String str1 ("ABCD"); cout<<str1<<endl;str1. Pushback (' e '); str1. Pushback (' F '); str1. Pushback (' G '); str1. Pushback (' h '); str1. Pushback (' I '); cout<<str1<<endl;cout<<str1. Size () <<endl;} void Text3 () {String str1 ("Hello"); String str2 ("Hello World"); String STR3 (str2); str1+= ""; str1+= "World"; cout<<str1<<endl;str2. Insert (6, "abc"); Cout<<str2<<endl;}
The method of deep copy implementation is there any more efficient way to Mulao? Of course, that's the copy-on-write, and we found that the copy constructor implemented in the above-mentioned version of the deep copy also re-opens up space for the new object (to prevent the sequelae of a shallow copy: a shallow copy is a value copy so that two pointers point to the same space, which can cause problems when the space is reconstructed multiple times) That Mulao if we inherit the sequela of the shallow copy- and we have multiple pointers pointing to the same piece of space, we just need to set a pointer variable so that it records the number of pointers to that space, as long as the pointer variable's content is 1, we release the space, or we let the counter minus 1. This is the main idea of copy-on-write, so let's use the copy-on-write method to implement a simple string class.method of copy on write time
Copy-on-write mode class String{friend ostream& operator<< (ostream & os,string &s);p ublic:string (const char * Str= ""): _str (new Char[strlen (str) +1+4]) {cout<< "Construct" <<endl;_str+=4;* ((int *) (_str-4)) =1;strcpy (_STR, STR);} String (string &s) {cout<< "Copy Construction" <<endl;++* ((int *) (s._str-4)); _str=s._str;} String &operator= (const string &s) {cout<< "assignment Statement" <<endl;if (--* (int *) (_str-4) = = 0) {delete[] (_ STR-4);} + + (* (int *) (s._str-4)); _str=s._str;return *this;} Char &operator[] (int index)//write copy {assert (index >= 0 && Index < (int) strlen (_STR)); if (* (int *) (_str-4) > 1) {--* (int *) (_str-4), Char *tmp=new Char[strlen (_STR) +5];strcpy (TMP+4,_STR);d elete[] (_str-4); _str=tmp+4;* (int *) (_str-4) = 1;} return _str[index];} ~string () {cout<< "destructor" <<endl;if (--* (int *) (_str-4) = = 0) {cout<< "release" <<endl;delete[] (_str-4);} Private:char *_str;};o stream& operator<< (ostream &os,string &s) {Os<<s._str;return os;}
Here we place the position of the counter pointed by the pointer at the first four bytes of the data spacetest Case:
void Test1 () {String str1 ("ABCD");cout<<str1<<endl; String str2 (str1);cout<<str2<<endl; String Str3;str3=str1;cout<<str3<<endl;} void Test2 () {String str1 ("ABCD");cout<<str1<<endl; String str2;str2=str1;cout<<str2<<endl;str2[2]= ' w '; Cout<<str2<<endl;}
For more detailed information, see: Http://coolshell.cn/articles/10478.htmlOVER !!!!
Implementation of simple Sting class in C + +