String Class (String), familiar with memory management and copy control
#include <iostream>//#include <cstring>usingstd::cout;usingstd::cin;classstring{usingiterator =Char*; Friend Std::ostream&operator<< (Std::ostream &,ConstString &); Friend Std::istream&operator>> (Std::istream &, String &); Friend Stringoperator+ (ConstString &ConstString &); Friend Stringoperator+ (ConstString &Const Char*);//for non-class functions, the parameters of the class type must exist in the parameter;Friend Stringoperator+ (Const Char*,ConstString &);//Otherwise, it conflicts with the default type of operatorFriend unsignedintGetline (Std::istream &, String &); Public: String (Const Char*RHS ="Hello, World");//constructor, default to "Hello, world" usually we can default to nullString (ConstString &);//copy ConstructorString &operator= (Conststring&);//Copy assignment operatorString &operator= (Const Char*);//Copy assignment operatorString &operator+= (Conststring&); String&operator+= (Const Char*); Char operator[] (int); Iterator begin (); Iterator End (); String& Push_back (Const Char); String&Clear (); ~string () {delete [] data;}// DestructorsPrivate: Char*data;}; Std::ostream&operator<< (Std::ostream &,ConstString &); Std::istream&operator>> (Std::istream &, String &); inline string::string (Const Char*RHS) { if(!RHS)//The RHS must first be checked for NULL, and for null copies, the unknown address is readdata =New Char[1]{0};//because our destructor calls the Delete, we have to open up a space,//Otherwise the code deletes an error space when the destructor is called Else{Data=New Char[Strlen (RHS) +1]; strcpy (data, RHS); }}inline String& String::operator= (Conststring& RHS)//Copy Assignment Operation{ This->data =New Char[Strlen (Rhs.data) +1]; strcpy ( This-data, Rhs.data); return* This;} Inline String& String::operator= (Const Char*RHS)//Copy assignment operator{ This->data =New Char[Strlen (RHS) +1]; strcpy ( This-data, RHS); return* This;}
- class method implementation
#include"String.h"Inline string::string (ConstString &RHS)//copy Constructor{Data=New Char[Strlen (Rhs.data) +1];//the reason for every +1 is that strlen does not contain the last 'strcpy (data, rhs.data);} Std::ostream&operator<< (Std::ostream &os,ConstString &RHS) {OS<<Rhs.data; returnOS;} Std::istream&operator>> (Std::istream & is, String &RHS) { is>>Rhs.data; return is;} String& String::operator+= (ConstString &RHS) { if(!rhs.data)//if the data for the class to be added is NULL, you do not need to process the return* This; Else if(!data)//if the original data is null, then copy the subsequent data directly; because of the above judgment, rhs.data! = NULL; { This->data =New Char[Strlen (Rhs.data) +1]; strcpy ( This-data, Rhs.data); return* This; } Else //data! = NULL && Rhs.data! = null { Char*tmp =New Char[Strlen ( This->data) +1]; strcpy (TMP, This-data); This->data =New Char[Strlen (data) + strlen (rhs.data) +1]; strcpy (data, TMP); strcat (data, rhs.data); Free(TMP); return* This; }}string& String::operator+= (Const Char*RHS) { if(!RHS)//if the data for the class to be added is NULL, you do not need to process the return* This; Else if(!data)//if the original data is null, then copy the subsequent data directly; because of the above judgment, rhs.data! = NULL; { This->data =New Char[Strlen (RHS) +1]; strcpy ( This-data, RHS); return* This; } Else //data! = NULL && Rhs.data! = null { Char*tmp =New Char[Strlen ( This->data) +1]; strcpy (TMP, This-data); This->data =New Char[Strlen (data) + strlen (RHS) +1]; strcpy (data, TMP); strcat (data, RHS); Free(TMP); return* This; }}stringoperator+ (ConstString &LHS,ConstString &RHS) {String tmp (LHS); TMP+=RHS; returntmp;} Stringoperator+ (ConstString &LHS,Const Char*RHS) {String tmp (LHS); TMP+=RHS; returntmp;} Stringoperator+ (Const Char*LHS,ConstString &RHS) {String tmp (LHS); TMP+=RHS; returntmp;} String::iterator String::begin () {returndata;} String::iterator String::end () {returnData +strlen (data);}CharString::operator[] (intindex) { if(Index > strlen (data)-1|| Index <0) {cout<<"Index Error"; return 0; } Else return* (Data +index);} String& String::p ush_back (Const Charch) { Char*tmp =New Char[Strlen (data) +2]; strcpy (tmp, data); * (tmp + strlen (data)) = CH;//Data + strlen (data) is the original '* (tmp + strlen (data) +1) =' /'; Data=New Char[Strlen (data) +2]; strcpy (data, TMP); //Free (TMP);Delete[] tmp;//Delete [] tmp = FREE (TMP): The suspect delete is the free package return* This;} String&string::clear () {delete[] data; Data=New Char[]{0}; return* This;} unsignedintGetline (Std::istream & is, String &RHS) { Chartmp; Rhs.clear (); while( is.Get(TMP)) { if(TMP && tmp! ='\ n') Rhs.push_back (TMP); Else Break; } returnstrlen (rhs.data);}
First write the beginning, the back can be reused it, such as + + +;
The destructor needs to use delete [] data because there is a need for space in many operations, so in the default constructor it is necessary to open up a space, because when the class calls the destructor for some reason, a space is required for the delete to use.
It's also possible to use smart pointers, so you don't need a delete
String Class (C + + Exercise II)