//head_h #include<iostream> //using std::cout; //using std::endl; using namespace std; class Mystring{ private: char* str; public: //constructors Mystring(); Mystring(char []); Mystring(Mystring &); ~Mystring(); //访问器成员 char * getstr(); int getLength();//返回字串的长度 //功能函数 void show();//输出字串内容 Mystring operator + (Mystring );//Mystring类对象之间相加 //Mystring& operator + (char []);//Mystring与C风格字串相加 bool operator > (Mystring &); //bool operator > (char []); char operator [] (int ); Mystring& operator = (char []); Mystring& operator = (Mystring & temp); }; //func_cpp #include"head.h" //非类成员函数 int length(char temp[])//返回char[]字串的长度(不含‘/0’) { int len=0; for(int i=0;;i++) { if(temp[i]=='/0')break; ++len; } return len; } char* strPlus(char *str1,char *str2)//实现将两个字串相加[是否会有内存溢出呢??] { //按两字符串的长度和进行申请空间,不会溢出 int size=length(str1)+length(str2)+1; char* tempStr=new char[size]; int lenOfStr1=length(str1); for(int i=0;i<length(str1);i++)tempStr[i]=str1[i]; for(i=length(str1);i<size;i++)tempStr[i]=str2[i-lenOfStr1]; tempStr[size]='/0'; return tempStr; } //constructors Mystring::Mystring() { str=0; } Mystring::Mystring(char a[]) { int size=length(a); if(str=new char[size+1])//检查内存分配是否成功@@! {for(int i=0;i<size;i++)str[i]=a[i]; str[size]='/0';} //cout<<"构造函数调用.字串为:"<<str<<endl; else cout<<"内存不足,对象未能成功生成!"<<endl; } Mystring::Mystring(Mystring &a) { int size=a.getLength(); if(str=new char[size+1])//检查内存分配是否成功@@! {for(int i=0;i<size;i++)str[i]=a[i]; str[size]='/0';} //cout<<"拷贝构造函数调用.字串为:"<<str<<endl; else cout<<"内存不足,对象未能成功生成!"<<endl; } Mystring::~Mystring() { delete []str; } //访问器成员 char * Mystring::getstr()//??这样把str地址传出来,是否破坏了对象私有成员的受保护的特性呢?是否就可以恶意修改似有成员呢?用const可以避免恶意修改吗? { //所以就不要把地址传出来,直接在show函数里,cout<<str; 或者按你的,返回const *也可以 return str; } int Mystring::getLength()//返回字串的长度,不包含/0!! { return length(str); } //功能函数 void Mystring::show()//输出字串内容 { cout<<getstr();//getstr返回的是一个指针 } Mystring Mystring::operator + (Mystring temp)//Mystring类对象之间相加..加法操作要分配一个新的内存空间,因为不能修改加数和被加数 { char* tempStr = strPlus(str,temp.str); Mystring newMystr=Mystring(tempStr); return newMystr; } bool Mystring::operator > (Mystring &tempS){ int size2=tempS.getLength(); int size1=this->getLength(); if(size1>size2)size1=size2;//此时size1为串长度的最小值 for(int i=0;i<size1;i++) {if(str[i]>tempS.str[i])return true; else return false;} return false;//直至串1比较完仍然完全相同,则串2比较大 }//未考虑两个字串完全相等的情况,如果完全相等会输出串2比串1大 char Mystring::operator [] (int order){ int sizeOfStr=this->getLength(); if(order<sizeOfStr)return str[order]; else cout<<"下标越界!将输出字串的第一个字符:";return str[0]; } /*Mystring& Mystring::operator = (char temp[])//【】错在哪里??(我已修改,请自己理解一下,返回类型为引用,不能返回局部对象) { //其实这样还是不好,会很容易出错,还是建议用下面那种深拷贝 Mystring* newMystr = new Mystring(temp); str=newMystr->str; return *this; } */ Mystring& Mystring::operator = (char temp[]) { int size=length(temp); str = new char[size+1]; strcpy(str, temp); return *this; } Mystring& Mystring::operator = (Mystring & temp) { if(str)delete []str; str=new char[temp.getLength()+1]; strcpy(str, temp.str); return *this; } //main_cpp //【提示】1、字符串对象的表达:一个字符数组 //2、需要的操作:参数构造、运算符重载等,注意下标运算符[]重载中下表合法性判断,如果越界给出提示。 #include"head.h" int main(){ Mystring s1("good"), s2("student"),s3,s4; s3="hello"; s3.show(); cout<<endl; s4=s1+s2; //拼接 s4.show(); //输出s4, 即goodstudent cout<<endl; cout<<s4[3]<<endl; //重载下标运算符,即输出d。 cout<<s1[6]<<endl; //可对下标合法性进行判断,越界给出恰当提示 if(s1>s2) { Mystring t=s1; s1=s2;s2=t;} //串拷贝 if(s1>s3) { Mystring t=s1; s1=s3;s3=t;} if(s2>s3) { Mystring t=s2; s2=s3;s3=t;} cout<<"按照从小到大的顺序输出三个串:"; s1.show(); cout<<'/t'; s2.show(); cout<<'/t'; s3.show(); cout<<endl; //输出结果应为good hello student system("pause"); return 0; } 本习题常见错误: 1:析构出错: 如果数组越界使用的话,析构时便会出错,但编译和连接均没有问题,运行时会崩溃 2:浅复制 将指针直接赋给另一个指针