#include <iostream>
//#include <string>
using namespace std;
/*---------------------------------
创建并实现字符串类的各种功能
18.51.创建String类~18.65.为String类添加字符串加等功能
---------------------------------*/
class String
{
public:
String();
~String(){cout<<"析构函数执行"<<endl; delete []str;len=0;}
String(const char * const ch);
String(const String &rs);//18.54.用复制构造函数实现字符串的初始化
//String(unsigned short int length);//仅仅提供给重载+调用的构造函数,设置为私有成员
int getlen()const{ return len;}//定义为const修饰的成员函数
//下面最左端的const意指函数返回的指针所指数据是常量,不可修改,只可读
const char* getstr() const{return str;}//靠近花括号的const,其修饰的成员函数体中不能修改任何成员变量(除非该成员变量是mutable修饰的)
//不能调用非const成员函数,因为非const成员函数具备修改成员变量的权限
char& operator[](unsigned short int length);//operator前若有"&",表示按引用返回;无"&",表示按值返回 18.53.限制数组越界
char operator[](unsigned short int length)const;//无"&",表示按值返回 18.54.用复制构造函数实现字符串的初始化1
String& operator=(const String &rs);
String operator+(const String &rs);
void operator+=(const String &rs);
friend ostream& operator<<(ostream &o,const String &str)
{
o<<"重载<<:"<<str.str;//重载输出
//o<<str.str;//重载输出
return o;
}
friend istream& operator>>(istream &o,String &str)
{
cout<<"重载>>:";//重载输入,18.59.用重载输入运算符函数实现字符串的输入
o>>str.str;
//str.len=strlen(str.str);
return o;
}
friend bool operator<(const String &str1,const String &str2)
{
if(strcmp(str1.str,str2.str)<0)
return 1;
return 0;
}
friend bool operator>(const String &str1,const String &str2)
{
if(strcmp(str1.str,str2.str)>0)
return 1;
return 0;
}
friend bool operator==(const String &str1,const String &str2)
{
if(strcmp(str1.str,str2.str)==0)
return 1;
return 0;
}
private:
String(unsigned short int length);//仅仅提供给重载+调用的构造函数,设置为私有成员
int len;
char *str;
};
void String::operator+=(const String &rs)//18.65.为String类添加字符串加等功能
{
cout<<"operator+=执行"<<endl;
int total=len+rs.getlen();
String temp(total);
for(int i=0;i<len;i++)
{ temp[i]=str[i];} //temp是String类,故其下标运算符[]将被重载
for(i=0;i<rs.getlen();i++)
{ temp[i+len]=rs[i];}//由于rs是const String类,故其下标运算符[]将被重载
temp[total]='\0';
*this=temp;
}
String String::operator+(const String &rs)//18.61.为String类添加字符串相加功能1
{
cout<<"operator+执行"<<endl;
int total=len+rs.getlen();
String temp(total);
for(int i=0;i<len;i++)
{ temp[i]=str[i];} //temp是String类,故其下标运算符[]将被重载
for(i=0;i<rs.getlen();i++)
{ temp[i+len]=rs[i];}//由于rs是const String类,故其下标运算符[]将被重载
temp[total]='\0';
return temp;//按值返回的时候,会自动调用复制构造函数String(const String &rs);
//完毕之后,自动调用析构函数,析构掉对象temp
}
//18.57.用重载赋值运算符函数实现字符串赋值功能
String& String::operator=(const String &rs)
{
cout<<"operator=执行"<<endl;
if(this==&rs)
{ return *this;}
delete []str;//this指向的被赋值的字符数组
len=rs.getlen();
str=new char[len+1];
for(int i=0;i<len;i++)
{ str[i]=rs[i];}//由于rs是const String类,故其下标运算符[]将被重载
str[len]='\0';
return *this;
}
char String::operator[](unsigned short int length)const//按值返回
{
cout<<"operator[] const执行"<<endl;
if(length>len)
{ return str[len-1];}
else
{ return str[length];}
}
char& String::operator[](unsigned short int length)//重载函数-类外定义书写格式
{
cout<<"operator[]执行"<<endl;
if(length>len)
{ return str[len-1];}
else
{ return str[length];}
}
//18.51.创建String类
String::String()
{
cout<<"执行不带参的构造函数"<<endl;
len=0;
str = new char[1];
str[0]='\0';
}
//18.52.创建可自动调节大小的String类字符串对象
String::String(const char * const ch)//如果const位于*左侧,表示指针所指数据是常量,不能通过解引用修改该数据,指针本身是变量.
{ //如果const位于*右侧,表示指针本身是常量,不能指向其他内存地址,指针所指的数据可以通过解引用修改。
cout<<"执行带参的构造函数"<<endl;
len=strlen(ch);
str =new char[len+1];
for(int i=0;i<len;i++)
{
str[i]=ch[i];
}
str[len]='\0';
}
String::String(unsigned short int length)//构造一个指定空间大小的空字符串
{
cout<<"执行带字符串长度参数的构造函数"<<endl;
len=length;
str =new char[len+1];
for(int i=0;i<=len;i++)
{
str[i]='\0';
}
}
//18.54.用复制构造函数实现字符串的初始化
String::String(const String &rs)
{
cout<<"用复制构造函数实现字符串的初始化"<<endl;
len=rs.getlen();//必须要是const修饰的成员函数
str =new char[len+1];
for(int i=0;i<len;i++)
{
str[i]=rs[i];//由于rs是const String类,故其下标运算符[]将被重载
}
str[len]='\0';
}
int main()
{
String str1;//18.51.创建String类
cout<<"str1:"<<str1.getstr()<<endl<<"共计"<<str1.getlen()<<"个字符"<<endl<<endl;
String str2("hello baby");//18.52.创建可自动调节大小的String类字符串对象
cout<<"str2:"<<str2.getstr()<<endl<<"共计"<<str2.getlen()<<"个字符"<<endl<<endl;
char *temp="study";
String str3(temp);//18.52.创建可自动调节大小的String类字符串对象
cout<<"str3:"<<str3.getstr()<<endl<<"共计"<<str3.getlen()<<"个字符"<<endl;
cin>>str3[-1];//18.53.限制数组越界
cout<<"str3:"<<str3.getstr()<<endl<<"共计"<<str3.getlen()<<"个字符"<<endl<<endl;
String str4=str3;//18.54.用复制构造函数实现字符串的初始化1
cout<<"str4:"<<str4.getstr()<<endl<<"共计"<<str4.getlen()<<"个字符"<<endl<<endl;
String str5;
str3="nam";//编译器首先将字符串"name转化为一个无名String对象",然后赋值
str3=str4=str5;//执行两次重载的赋值操作
cout<<"str3:"<<str3.getstr()<<endl;
cout<<"str4:"<<str4.getstr()<<endl;
cout<<"str5:"<<str5.getstr()<<endl<<endl;
cout<<str1<<endl<<str2<<endl;//18.58.用重载输出运算符函数实现字符串输出
str2="abd";
str3="abc";
str4="abc";
cout<<"str2"<<str2<<endl;
cout<<"str3"<<str3<<endl;
cout<<"str4"<<str4<<endl;
bool check;
check= (str3==str4);
cout<<"str3==str4 比较结果: "<<check<<endl;
check= (str2>str4);
cout<<"str2>str4 比较结果:"<<check<<endl;
check= (str2<str4);
cout<<"str2<str4 比较结果:"<<check<<endl<<endl;
String str6;
str6=str2+str3;//赋值给str6完成后,等号右边赋值构造函数创建的临时对象将被析构
cout<<"str6:"<<str6<<endl<<endl;
str2+=str3;
cout<<"str2:"<<str2<<endl;
/* 很奇怪 下面的代码会导致运行时崩溃
cin>>str5;//18.59.用重载输入运算符函数实现字符串的输入
cout<<str5<<endl;
// cout<<"str5:"<<str5.getstr()<<endl<<"共计"<<str5.getlen()<<"个字符"<<endl<<endl;
*/
return 0;
}
运行结果:
执行不带参的构造函数
str1:
共计0个字符
执行带参的构造函数
str2:hello baby
共计10个字符
执行带参的构造函数
str3:study
共计5个字符
operator[]执行
g
str3:studg
共计5个字符
用复制构造函数实现字符串的初始化
operator[] const执行
operator[] const执行
operator[] const执行
operator[] const执行
operator[] const执行
str4:studg
共计5个字符
执行不带参的构造函数
执行带参的构造函数
operator=执行
operator[] const执行
operator[] const执行
operator[] const执行
析构函数执行
operator=执行
operator=执行
str3:
str4:
str5:
重载<<:
重载<<:hello baby
执行带参的构造函数
operator=执行
operator[] const执行
operator[] const执行
operator[] const执行
析构函数执行
执行带参的构造函数
operator=执行
operator[] const执行
operator[] const执行
operator[] const执行
析构函数执行
执行带参的构造函数
operator=执行
operator[] const执行
operator[] const执行
operator[] const执行
析构函数执行
str2重载<<:abd
str3重载<<:abc
str4重载<<:abc
str3==str4 比较结果: 1
str2>str4 比较结果:1
str2<str4 比较结果:0
执行不带参的构造函数
operator+执行
执行带字符串长度参数的构造函数
operator[]执行
operator[]执行
operator[]执行
operator[] const执行
operator[]执行
operator[] const执行
operator[]执行
operator[] const执行
operator[]执行
operator[]执行
用复制构造函数实现字符串的初始化
operator[] const执行
operator[] const执行
operator[] const执行
operator[] const执行
operator[] const执行
operator[] const执行
析构函数执行
operator=执行
operator[] const执行
operator[] const执行
operator[] const执行
operator[] const执行
operator[] const执行
operator[] const执行
析构函数执行
str6:重载<<:abdabc
operator+=执行
执行带字符串长度参数的构造函数
operator[]执行
operator[]执行
operator[]执行
operator[] const执行
operator[]执行
operator[] const执行
operator[]执行
operator[] const执行
operator[]执行
operator[]执行
operator=执行
operator[] const执行
operator[] const执行
operator[] const执行
operator[] const执行
operator[] const执行
operator[] const执行
析构函数执行
str2:重载<<:abdabc
析构函数执行
析构函数执行
析构函数执行
析构函数执行
析构函数执行
析构函数执行
Press any key to continue