参考书籍:面向对象程序设计C++
一、项目构架
(1)main_string.cpp
#include "mystring.h"
#include "iostream"
using namespace std;
int main()
{
String s1; //构造一个空的字符串
String s2("Hello"); //含参数的构造函数
String s3 =s2; //深度复制copy构造函数
String s4;
s1 = s2; //通过重载operator = 完成字符串的赋值
s2 =s2; //在operator =中值怎么实现自己赋值
s1 =s2 =s3; //这个是在operator中怎么实现的
cout << s2 << endl;
}
(2) mystring.h
#ifndef STRING_H_INCLUDED
#define STRING_H_INCLUDED
#include "iostream"
using std::ostream;
class String
{
public:
String(); //构造空字符串的构造函数
String(const char *p ); //含有内容的构造函数
String(const String &p); //copy构造函数
~String(); //析构函数
//成员函数
String& operator = (const String &rhs); //赋值的重载
friend ostream& operator<<(ostream &os,const String &s); //输出流,想一想为什么只能声明为友元函数
private:
char *ptr;
};
#endif
(3) mystring.cpp
#include "mystring.h"
#include "iostream"
using namespace std;
String::String()
{
/*
//思考一下:默认的为什么不通过空指针(NULL pointer进行赋值)
ptr =NULL;//这样写是不会报错误的,但是在程序中充满了是不是null pointer的判断,这样会非常的复杂
*/
ptr = new char[1];
ptr ='\0';
}
String::String(const char *p ) //含有内容的构造函数
{
ptr = new char[strlen(p)+1]; //加1是为了保证最后的空字符
strcpy(ptr,p);
cout << ptr<< endl;
}
String::String(const String &p) //复制构造函数
{
ptr = new char[strlen(p.ptr)+1]; //加1是为了保证最后的空字符
strcpy(ptr,p.ptr);
}
String& String::operator = (const String &rhs) //赋值的重载
{
if(this!= &rhs) //考虑到非自赋值。也就是说不能写成s2=s2,
{
//思考为什么加入delete [ ]ptr ;释放旧的内存空间
//原因是因为赋值运算符(assignment operator 不同于copy ctor,赋值运算符没有创建新的对象,只是修改左边的值)
//在修改左侧的值的时候,应该把原来的旧内存释放掉,重新申请新的内存,如果不释放旧的内存而直接申请新的内存空间,会导致旧的内存没有释放,
//导致内存的泄露
delete []ptr;
ptr = new char[strlen(rhs.ptr)+1]; //加1是为了保证最后的空字符
strcpy(ptr,rhs.ptr);
}
return *this;
}
String::~String()
{
delete []ptr; //动态内存的释放
ptr = NULL; // 将野指针进行释放
}
ostream& operator<<(ostream &os,const String &s)
{
os << s.ptr;
return os;
}
输出结果: