C++高校基础教程_11_10_实例研究:String类
C++大学基础教程_11_10_实例研究:String类
//String.h #ifndef STRING_H_ #define STRING_H_ #include <iostream> using namespace std; class String { //,将重载运算符<< 和 >> 设为友元函数,二元运算符的重载运算符函数可以作为成员 //函数的条件是仅当左操作数是该类所在类的对象时; friend ostream &operator<<(ostream &,const String &); friend istream &operator>>(istream &,String &); public: String(const char * = "");//构造函数,将char型转换成String型 String(const String &);//拷贝构造函数 ~String(); const String &operator=(const String &);//两字符串复制函数 const String &operator+=(const String &);//两字符串相加 const String &operator+=(const char *);//两字符串相加 bool operator!();//判断是否为空字符串 bool operator==(const String &) const;//判断是否两字符串相等 bool operator!=(const String &right) const //判断两字符串是否不等 { return !(*this == right); } bool operator<(const String &) const; bool operator>(const String &right) const //写内联函数的时候忘记写参数,!!!!! { return right < *this; } bool operator<=(const String &right) const { return !(*this > right); } bool operator>=(const String &right) const { return !(*this < right); } char &operator[](int);//重载[], char operator[](int) const; void operator()(int,char) const;//替换某个位置的元素 String operator()(int,int = 0) const;//截取两个数字位之间的字符 void setString(const char *);//效用函数 private: int length;//字符串中字符个数 char *sPtr;//指针sPtr,指向代表字符串的额动态内存分配 }; #endif
//String.cpp #include "String.h" #include <iostream> #include <iomanip> using namespace std; istream &operator>>(istream &input,String &right) { char *temp = new char[100]; input >> setw(100) >> temp; right = temp; delete [] temp; return input; } ostream &operator<<(ostream &output,const String &right) { int i; for(i=0;i<right.length;i++) //ouput << right.sPtr; output << right.sPtr[i]; return output; } void String::setString(const char *string) { sPtr = new char[strlen(string)+1];//把这一句写成[strlen(string+1)] //我是得有多有才!!! if(string!=0) { for(int i=0;i<strlen(string);i++) sPtr[i] = string[i]; sPtr[strlen(string)] = '\0'; } /* if(string!=0) strcpy(sPtr,string); */ else sPtr = '\0'; } String::String(const char *right) :length((right!=0)? strlen(right) : 0) //构造器 { cout << "Conversion (and default) constructor: " << right << endl; setString(right); } String::String(const String &s)//拷贝构造函数 :length(s.length) { cout << "Copy constructor: " << s.sPtr << endl; setString(s.sPtr); } String::~String() { cout << "Destructor: " << sPtr << endl; delete [] sPtr; } //两字符串复制函数 const String &String::operator=(const String &right) { cout << "operator= called." << endl; if(&right != this) //if(sPtr != right.sPtr)//防止同一字符串自我复制 { delete [] sPtr; length = right.length; /* sPtr = new char[right.length]; for(int i=0;i<length;i++) sPtr[i] = right.sPtr[i]; */ setString(right.sPtr); } else cout << "Attempted assignment of a string to itself." << endl; return *this; } const String &String::operator+=(const String &right)//两字符串相加 { size_t newLength= length + right.length; char *temp = new char[newLength+1]; for(int i=0;i<length;i++) //strcpy(temp,sPtr); temp[i] = this->sPtr[i]; strcpy(temp+length,right.sPtr); delete [] sPtr; sPtr = temp; length = newLength; return *this; } const String &String::operator+=(const char *s)//两字符串相加 { if(s != 0) { size_t newLength = length + strlen(s); char *temp = new char[newLength+1]; strcpy(temp,sPtr); for(int i=length;i<newLength;i++) temp[i] = s[i-length]; temp[newLength] = '\0'; delete [] sPtr; sPtr = temp; length = newLength; } return *this; } bool String::operator!()//判断是否为空字符串 { //(length == 0)? true: false; if(length == 0) return true; return false; } bool String::operator==(const String &right) const//判断是否两字符串相等 { if(length == right.length) { for(int i=0;i<length;i++) if(sPtr[i] != right.sPtr[i]) return false; return true; } return false; } //比较两个字符串如abbbbbbb<abbb false // askjdh<hj true //若两者头部有相同的部分,则比较不同的部分如a<h bool String::operator<(const String &right) const { if(length < right.length) { //先判断两个字符串有没有不相同的 for(int i=0;i<length;i++) { if(sPtr[i] != right.sPtr[i]) { if(sPtr[i] < right.sPtr[i]) return true; // abb<abccc ? true return false;//abb<abac ? false } } return true;//abb<abbkajsfh ? true } else if(length == right.length) { for(int i=0;i<length;i++) { if(sPtr[i] != right.sPtr[i]) { if(sPtr[i] < right.sPtr[i]) return true; //abbbb<abcdc ? true return false; //abbbb<ababb ? false } } return false; //abbbb<abbbb ? false } else //length > right.length { for(int i=0;i<right.length;i++) { if(sPtr[i] != right.sPtr[i]) { if(sPtr[i] < right.sPtr[i]) return true; //abbbb<abd ? true return false; //abbbb<aba ? false } } return false;// abbbb<ab ? false }//end else }//end operator< function char &String::operator[](int number)//重载[], { if(number<0 || number>=length) { cout << "Error: number " << number << "out of range." << endl; exit(1); } return sPtr[number]; } char String::operator[](int number) const { if(number<0 || number>=length) { cout << "Error: number " << number << "out of range." << endl; exit(1); } return sPtr[number]; } String String::operator()(int index,int subLength) const//截取两个数字位之间的字符 { int len; if(index<0 || subLength<0 || index>subLength) return ""; else if(index>=0 && subLength<=length) len = subLength; else if(index>=0 && subLength>length) len = length-index; char *tempPtr = new char[len+1]; strncpy(tempPtr,&sPtr[index],len); tempPtr[len] = '\0'; String tempString(tempPtr); delete [] tempPtr; return tempString;//写成return temPtr运行的时候会出现乱码 } void String::operator()(int number,char s) const//替换某个位置的元素 { this->sPtr[number] = s; }
//_11_10_main.cpp #include "String.h" #include <iostream> using namespace std; int main() { {//这一对大括号是为了把析构函数的调用弄出来加上去的,可以去掉 String str1("happy"); String str2(" birthday"); String str3; cout << "str1 is \"" << str1 << "\"; str2 is \"" << str2 << "\"; str3 is \"" << str3 << "\"\n"; cout << boolalpha << "The results of comparing str2 and str1:" << "\nstr2 == str1 yields " << (str2==str1) << "\nstr2 ! = str1 yields " << (str2!=str1) << "\nstr2 > str1 yields " << (str2>str1) << "\nstr2 < str1 yields " << (str2<str1) << "\nstr2 >= str1 yields " << (str2>=str1) << "\nstr2 <= str1 yields " << (str2<=str1) << endl; cout << "Testing !str3:" << endl; if(!str3) { cout << "str3 is empty;assigning str1 to str3;" << endl; str3 = str1; cout << "str3 is \"" << str3 << "\"\n"; } cout << "str1 += str2 yields " << endl; str1 += str2; cout << "str1 = " << str1 << endl; cout << "str1 += \" to you \" yields" << endl; str1 += " to you"; cout << "str1 = " << str1 << endl; cout << "The substring of str1 starting at \n" << "location 0 for 14 characters,str1(0,14), is:\n" << str1(0,14) << endl;//对应的函数部分有错误提示 cout << "The substring of str1 starting at \n" << "location 15,str1(3,15), is:\n" << str1(3,15) << endl; String *sPtr0 = new String(str1); cout << "*sPtr0 = " << *sPtr0 << endl; cout << "assigning *sPtr0 to *sPtr0" << endl; *sPtr0 = *sPtr0; cout << "*sPtr0 = " << *sPtr0 << endl; *sPtr0 = str2;//注意咯!!!!! cout << "*sPtr0 = " << *sPtr0 << endl; delete sPtr0;//写成这样就会错误,delete [] sPtr0;因为这是一个指向对象的指针啊啊啊 str1(0,'H'); str1(6,'B'); cout << "str1 after atr1[0] = 'H' and str[6] = 'B' is:\n" << str1 << endl; } system("pause >> cout"); return 0; }