Original: http://noalgo.info/382.html
String is an important type in C + +, and programmers often encounter details about string in C + + interviews and even require that class be implemented on the spot. Just because of the temporal relationship, it may only be required to implement the key parts of constructors, destructors, copy constructors, and so on.
The implementation of string involves a lot of basic knowledge of C + +, memory control and exception handling problems, careful study is very complex, this article mainly to do a simple summary and induction.
A holistic framework
In the interview due to the time, the interviewer generally does not require a very detailed function of the string, is generally required to implement the constructor, copy constructor, assignment function, destructor of a few very important parts. Because the string involves the management of dynamic memory, the default copy constructor only makes shallow copies at run time, that is, only the pointer to the memory area, which causes two objects to point to the same area of memory. If an object destroys or alters the area of memory, it causes the other object to run or make a logical error. At this point the programmer is required to implement these functions for deep replication, that is, not only copy pointers, but with the contents of the memory to copy.
In addition to the four required functions above, some additional content is implemented here.
- Several operator overloads, several of which are common operators, can deepen the understanding of string and operator overloading.
- Two commonly used functions, including string lengths and C-type strings.
- Two operator overloads for handling input and output, for ease of use, define these two operators as friend functions.
The framework for the overall class is shown below.
Class string{public:string (const char *STR = NULL),//General constructor string (const string &str);//copy constructor ~string ();// destructor string operator+ (const string &str) const;//overloads +string& operator= (const string &str);//Overloaded =string& operator+= (const string &str);//Overload +=bool operator== (const string &str) const;//overload ==char& operator[] (int n) const;//overload []size_t size () const;//get length const char* c_str () const;//get C string friend istream& operator>> (IStream & Amp;is, string &str);//input friend ostream& operator<< (ostream &os, String &str);//Output Private:char * data;//string size_t length;//length};
Note that some of the member functions of the class are const-decorated, indicating that the function does not make any modifications to the members of the class. The input parameters of some functions are also added with a const modifier, indicating that the function does not change the value of this parameter.
Two concrete Realization
The following is an implementation of member functions.
The same constructor applies a string array for string initialization, and the default string array is empty. There is no need to define the default value of the parameter in the function definition here, because it has already been declared in the class.
In addition, when the C function strlen is used, it is important to note that the string argument is empty and that calling strlen on a null pointer throws a memory error.
string::string (const char *STR)//General constructor {if (!str) {length = 0;data = new Char[1];*data = '} ';} Else{length = strlen (str);d ATA = new Char[length + 1];strcpy (data, str);}}
Copy constructors require a deep copy.
string::string (const String &STR)//copy constructor {length = Str.size ();d ata = new Char[length + 1];strcpy (data, str.c_str ());}
Destructors require the release of memory and the zeroing of the length.
String::~string ()//destructor {delete []data;length = 0;}
Overloaded string Join operation, this operation returns a new string.
String string::operator+ (const string &str) const//overloads +{string newstring;newstring.length = length + str.size (); Newstring.data = new Char[newstring.length + 1];strcpy (newstring.data, data); Strcat (Newstring.data, str.data); return NewString;}
Overloaded string assignment operation, this operation will change the value of the original string, in order to avoid memory leaks, the original requested memory is freed and then re-request a piece of the appropriate size of memory to hold the new string.
string& string::operator= (const String &STR)//heavy ={if (this = = &str) return *this;delete []data;length = Str.length;data = new Char[length + 1];strcpy (data, str.c_str ()); return *this;}
The overloaded string + = operation, in general, is the combination of the above two operations.
string& string::operator+= (const String &STR)//overload +={length + = Str.length;char *newdata = new Char[length + 1];str CPY (NewData, data), strcat (NewData, Str.data);d elete []data;data = Newdata;return *this;}
Overloads the equality relationship operation, defined here as an inline function to speed up the run.
inline bool string::operator== (const String &STR) const//overloads =={if (length! = str.length) return False;return strcmp ( Data, Str.data)? False:true;}
Overloading the string index operator makes a simple error handling when the last character is automatically read when the length is too large.
Inline char& string::operator[] (int n) const//overload []{if (n >= length) return data[length-1];//error handling else return Data[n ];}
Overloads two functions that read private members, reading both the length and the C string, respectively.
Inline size_t string::size () const//get length {return length;}
Overloaded input operator, first request a chunk of memory large enough to hold the input string, and then create a new string. This is a relatively simple implementation, many of the online direct Is>>str.data method is wrong, because it is not possible to determine the size of str.data and the size of the incoming string.
istream& operator>> (IStream &is, String &str)//input {char tem[1000]; Simply apply a piece of memory is >> tem;str.length = strlen (TEM), str.data = new Char[str.length + 1];strcpy (str.data, TEM);
Overloading the output operator simply outputs the contents of the string. Note that in order to achieve a continuous output like cout<<a<<b, the output stream needs to be returned. The above input is similar.
ostream& operator<< (ostream &os, String &str)//output {OS << str.data;return os;} Inline const char* STRING::C_STR () const//gets the C string {return data;}
Three functional tests
The code needs to be tested after the coding is complete, and the following is a simple but not rigorous test.
int main () {String s;cin >> s;cout << s << ":" << s.size () << endl;char a[] = "Hello", b[] = "World!"; String S1 (a), S2 (b), cout << S1 << "+" << s2 << "=" << S1 + s2 << Endl; String s3 = S1 + s2;if (S1 = = S3) cout << "first:s1 = S3" << endl;s1 + = s2;if (S1 = S3) cout << "Second : S1 = = S3 "<< endl;/* program Input Output: 123456789123456789:9hello + world! = helloworld! SECOND:S1 = = s3press any key to continue ... */}
Implementation of the String class in C + +