String
In My Learning life in C + + I found that the string class is very powerful, so we have to simulate it, and in the interview, simulate a string class is also a regular exam, but because of outside constraints we are not possible to simulate and the library string consistent ( The string in the C + + library is more powerful), so today we're only going to simulate the basic functions of string-constructors, copy constructors, destructors, assignment operator overloads, overloads of operator = +, overloads of operators [], C_STR (get a C-style character pointer, operable string ), Size,push_back,insert (deep copy), and the use of write-time copy Copy_on_write to implement the basic string class
The way of deep copy
Class String {friend Ostream &operator<< (ostream &os,string &s); public:string (const char *str= ""); The full default constructor that resolves the problem string (const string &ps) of the empty strings;
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);
Private:int _size;
int _capacity;
Char *_pstr;
}; Ostream &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&L
t;< "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+co UNT)?
(2*_capacity):(_capacity+count);
Char *tmp=new Char[_count];
strcpy (TMP,_PSTR);
DELETE[]_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, especially when implementing the assignment operator overload, we used two ways, and it is worth mentioning the use of the swap function to implement the overload of the assignment operator (no reference can be passed when the argument is passed). Because the application of the SWAP function is based on the creation of a temporary variable and the temporary variable is scoped, the destructor is automatically called for Destruction (modern method)
How to test deep copy
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; 5
str1[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 realizing the deep copy does that Mulao have a more efficient way? Of course, that is the write-time copy, and we find that the copy constructor implemented in the deep copy of the above version also opens the space for new objects (to prevent the sequelae of shallow copies: a shallow copy is a value copy that causes two pointers to be in the same space, and a problem occurs when the space is released multiple times on the same block of space. That Mulao if we inherit the sequelae of a shallow copy-let multiple pointers point to the same space, at this point we just need to set a pointer variable to record the number of pointers to this space, as long as the contents of the pointer variable 1 we release the space otherwise let the counter minus 1, which is the main idea of the copy, Let's use the write-time copy method to implement a simple string class.
Methods of writing-time copying
How to copy in writing class String {friend ostream& operator<< (ostream & os,string &s);
public:string (const char *str= ""): _str (new Char[strlen (str) +1+4]) {cout<< "constructs" <<endl;
_str+=4;
* (int *) (_str-4) = 1;
strcpy (_STR,STR);
} string (String &s) {cout<< "copy construct" <<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-time 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);
Delete[] (_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
};
ostream& operator<< (ostream &os,string &s) {os<<s._str;
return OS; }
Here we place the counter where the pointer points to the first four bytes of the data space
Test Cases:
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;
}
The above is a small set to introduce the C + + sting class of simple implementation method, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!