//字符串类_字符串对象的赋值与输出
#include <iostream>
#include <cstring>
using namespace std;
class Str //定义字符串类型
{
private:
char *str_p; //Str类的对象保存字符串,是将字符串保存到数据成员str_p指向的动态字符数组中
//str_p指向的动态数组长度恰好容纳字符串以及末尾的'\0',不会有多出的浪费空间
public:
Str(); //Str类的无参构造函数
Str(const char *p); //Str类的有参构造函数
int Str_len(); //返回保存的字符串长度
const char * getStr(); // 返回对象中的字符串
~Str(); //析构函数
friend ostream& operator << (ostream&,Str&); //声明重载运算符“<<”
void operator = (const char *p); //声明重载运算符=
void operator = (Str &str); //声明重载运算符=
};
// 获取str对象中的字符串
const char* Str::getStr()
{
return this->str_p;
}
//声明重载运算符= 参数为字符串
void Str::operator =(const char *p)
{
cout << "赋值前注销原来的字符串" << str_p << "占用的动态内存空间!" << endl;
// 释放原空间
delete [] this->str_p;
// 将新的内容进行拷贝
int len=strlen(p);
this->str_p=new char[len+1];
strcpy(this->str_p,p);
}
//声明重载运算符= 参数为Str对象
void Str::operator =( Str &str)
{
cout << "赋值前注销原来的字符串" << str_p << "占用的动态内存空间!" << endl;
// 释放原空间
delete [] this->str_p;
// 将新的内容进行拷贝
int len=strlen(str.getStr());
this->str_p=new char[len+1];
strcpy(this->str_p,str.getStr());
}
// 重载<<运算符的实现
ostream& operator<<(ostream& output,Str& str)
{
output<<str.str_p;
return output;
}
// 无参构造
Str::Str()
{
str_p=new char[5];
strcpy(str_p,"ccnu");
}
// 通过字符串构造
Str::Str(const char *p)
{
int len=strlen(p);
str_p=new char[len+1];
strcpy(str_p,p);
}
// 获取字符串长度
int Str::Str_len()
{
return strlen(str_p);
}
// 析构函数
Str::~Str()
{
cout<<"字符串"<<str_p<<"被注销!"<<endl;
delete [] str_p;
}
int main()
{
cout<<"创建对象s1"<<endl;
Str s1;
cout<<"输出s1中保存的字符串信息:";
cout<<s1<<endl<<endl;
cout<<"创建对象s2"<<endl;
Str s2("hello");
cout<<"输出s2中保存的字符串信息:";
cout<<s2<<endl<<endl;
cout<<"执行s2=123456操作"<<endl;
s2="123456"; //字符串常量"123456"复制到s2中保存,需要释放s2中之前保存的字符串占用的动态内存空间
cout<<"执行s2=123456之后,输出s2中保存的字符串信息:";
cout<<s2<<endl<<endl;
//前面的代码调试通过之后,再加入下面这段代码运行程序时,最后的对象注销环节会报错!
//分析错误原因(在主函数代码后面补充分析过程),并改正程序错误!
cout<<"执行s1=s2操作"<<endl;
s1=s2;
cout<<"执行s1=s2之后,输出s1中保存的字符串信息:";
cout<<s1<<endl<<endl;
return 0;
}
/*
在下面补充前面提到的错误原因
未报错
*/