📄 ep5_11.cpp
字号:
/* 5.11 完善自定义字符串类mystring,函数包括:构造函数、拷贝构造函数、析构函数,
并重载运算符[],=(分别用mystring和C字符串拷贝),+(strcat),+=,>,==(strcmp)。
*/
#include<iostream>
using namespace std;
const int n=256;
class mystring{
char str[n]; //存放字符串的数组容器
int maxsize; //最大可用元素数,可防止数组出界,提高健壮性
int last; //已用元素最大下标
public:
mystring(){
last=0;
maxsize=n;
str[0]='\0';
cout<<"缺省构造函数"<<endl;
}
mystring(char *s){//当C字符串过长,初始化时采用截尾处理
last=-1;
maxsize=n;
do{
last++;
str[last]=s[last];
}while(s[last]!='\0'&&last<maxsize-1);
str[last] ='\0'; //截尾处理时,必须加串结束符
cout<<"构造函数"<<endl;
}
mystring(mystring & ms){
last=-1;
maxsize=n;
do{
last++;
str[last]=ms.str[last];
}while(last<ms.last);
cout<<"拷贝构造函数"<<endl;
}
~mystring(){
cout<<"析构函数"<<endl;
}
void show(){//如需重载<<,则请参见9.3.3节,暂时未学到,替代的方法是改用一个show()函数
cout<<str<<endl;
}
char & operator[](int i){ //返回引用,可读可写
if(i>last) last=i; //下标运算符,可添加长度但不查边界
return str[i];
}
mystring operator=(mystring &);
mystring & operator=(char * ms);//这里重载的=是把C风格字符串赋给mystring
mystring operator+(mystring &);
mystring operator+=(mystring &);
bool operator<(mystring &);
bool operator>(mystring &);
bool operator==(mystring &);
};
mystring mystring::operator=(mystring & ms){
last=-1;
do{
last++;
str[last]=ms.str[last];
}while(last<ms.last);
return *this;
}
mystring & mystring::operator=(char* ms){ //这里返回值为引用,不调用拷贝构造函数
last=-1;
do{
last++;
str[last]=ms[last];
}while(ms[last]!='\0'&&last<maxsize-1);
str[last] ='\0'; //截尾处理时,必须加串结束符
return *this;
}
mystring mystring::operator+(mystring & ms){//注意+和+=的不同
mystring temp(*this);//+必须在一份拷贝上进行
int i=-1;
temp.last--;//串的结尾是结束符,连接时要覆盖掉
do{
temp.last++;
i++;
temp.str[temp.last]=ms.str[i];
}while(i<ms.last&&temp.last<maxsize-1);
temp.str[temp.last] ='\0'; //截尾处理时,必须加串结束符
return temp;//拷贝的临时变量生命期在调用它的表达式中
}
mystring mystring::operator+=(mystring & ms){//+=在对象自身进行
int i=-1;
last--;//串的结尾是结束符,连接时要覆盖掉
do{
last++;
i++;
str[last]=ms.str[i];
}while(i<ms.last&&last<maxsize-1);
str[last] ='\0'; //截尾处理时,必须加串结束符
return *this;
}
bool mystring::operator<(mystring & ms){ //重载<运算符
int i=0,k;
do{
k=str[i]-ms.str[i];
i++;
}while(k==0&&i<last&&i<ms.last);
if(k<0) return true;
if(i==last&&i!=ms.last) return true;
return false;
}
bool mystring::operator>(mystring & ms){ //重载>运算符
int i=0,k;
do{
k=str[i]-ms.str[i];
i++;
}while(k==0&&i<last&&i<ms.last);
if(k>0) return true;
if(i==ms.last&&i!=last) return true;
return false;
}
bool mystring::operator==(mystring & ms){
int i=0,k;
if(last!=ms.last) return false;
do{
k=str[i]-ms.str[i];
i++;
}while(k==0&&i<last);
if(k!=0) return false;
else return true;
}
int main(){
int i;
char *sp1="东南大学",*sp2="交通学院",*sp3="学生",*sp4="教师";
mystring ms1(sp1),ms2(sp2),ms3(sp3);//ms1,ms2,ms3是用构造函数生成
mystring ms4(ms3),ms5=ms3,ms6; //ms4,ms5是用拷贝构造函数生成;ms6用缺省构造函数生成
ms6=sp4; //ms6赋值是返回引用,不用拷贝构造函数
ms1.show();
ms2.show();
ms3.show();
ms4.show();
ms5.show();
ms6.show();
ms4=ms1+ms2+ms6;//注意temp和临时变量由拷贝构造函数生成
ms4.show();
ms1+=ms2+=ms3;
ms1.show();
if(ms1<ms4) {ms1.show();cout<<"应排在"<<endl;ms4.show();cout<<"之前"<<endl;}
else {ms1.show();cout<<"应排在"<<endl;ms4.show();cout<<"之后"<<endl;}
if(ms1>ms2) {ms1.show();cout<<"应排在"<<endl;ms2.show();cout<<"之后"<<endl;}
else {ms1.show();cout<<"应排在"<<endl;ms2.show();cout<<"之前"<<endl;}
ms6=ms1;//ms6赋值不是返回引用,必须调用拷贝构造函数建立临时对象
if(ms1==ms6) cout<<"串ms1与串ms6相同"<<endl;
ms1="C++ programming language";
i=0;
while(ms1[i]!='\0') cout<<ms1[i++];//读出
cout<<endl;
ms1[i++]='.';//写入
ms1[i]='\0';
i=0;
ms1.show();
return 0;
}
/*此例既是对第4章的复习也是一个提高。拷贝构造函数的应用请参阅4.4.2节末尾两项说明,
本例形参使用引用,仅在返回时调用了拷贝构造函数。运算符的重载请参阅4.5节。*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -