一、头文件的声明及布局
- 完整代码在文章末尾
#ifndef XXX
#define XXX
…… // 前置声明(第一板块)
…… // 类的声明(第二板块)
…… // 类的定义(第三板块)
#endif
二、类的声明
- 成员变量:字符指针。
private:
char* m_data;
- 构造函数。
- 成员函数。
三、构造函数
1.构造函数
- 调用默认构造函数定义的string对象应该是一个空对象。
构造函数声明:
public:
String(const char* cstr = 0);
构造函数定义:
#include<cstring>
inline
String::String(const char* cstr)
{
if (cstr)
{
m_data = new char[strlen(cstr) + 1];
strcpy(m_data, cstr);
}
else
{//空字符串
m_data = new char[1];
*m_data = '\0';
}
}
2.拷贝控制
- 对于含有指针的类,必须自己定义拷贝控制函数,包括拷贝构造函数,拷贝赋值函数,析构函数。如果没有自己定义拷贝控制操作,编译器会自动合成,这个时候可能会发生浅拷贝,从而导致同一份内存空间被释放两次。
- 拷贝构造函数定义了当用同类型的对象初始化本对象时做什么;拷贝赋值函数定义了当把同类型的对象赋值给本对象时做什么;析构函数定义了销毁对象时做什么。
- 拷贝赋值函数必须定义为成员函数。拷贝赋值函数必须进行自我检测,否则会释放掉原来的内存空间。
拷贝控制操作声明:
public:
String(const String& str);
String& operator=(const String& str);
~String();
拷贝控制操作定义:
//拷贝构造函数
inline
String::String(const String& str)
{
m_data = new char[strlen(str.m_data) + 1];
strcpy(m_data, str.m_data);
}
//拷贝赋值函数
inline
String& String::operator=(const String& str)
{
if (this == &str)//自我检测
return *this;
delete[]m_data;
m_data = new char[strlen(str.m_data) + 1];
strcpy(m_data,str.m_data);
return *this;
}
//析构函数
inline
String::~String()
{
if (m_data)
{
delete[]m_data;
m_data = NULL;
}
}
四、成员函数
char* get_str()const { return m_data; }
五、重载输出运算符
ostream& operator<<(ostream& os, const String& str)
{
return os << str.get_str();
}
六、完整代码及测试案例
1.头文件
#pragma once
#ifndef _MY_STRING_
#define _MY_STRING_
class String
{
public:
String(const char* cstr = 0);
String(const String& str);
String& operator=(const String& str);
~String();
char* get_str()const { return m_data; }
private:
char* m_data;
};
#include<cstring>
inline
String::String(const char* cstr)
{
if (cstr)
{
m_data = new char[strlen(cstr) + 1];
strcpy(m_data, cstr);
}
else
{ //空字符串
m_data = new char[1];
*m_data = '\0';
}
}
//拷贝构造函数
inline
String::String(const String& str)
{
m_data = new char[strlen(str.m_data) + 1];
strcpy(m_data, str.m_data);
}
//拷贝赋值函数
inline
String& String::operator=(const String& str)
{
if (this == &str)//自我检测
return *this;
delete[]m_data;
m_data = new char[strlen(str.m_data) + 1];
strcpy(m_data,str.m_data);
return *this;
}
//析构函数
inline
String::~String()
{
if (m_data)
{
delete[]m_data;
m_data = NULL;
}
}
#endif // !_MY_STRING_
2.主程序
#include<iostream>
using namespace std;
#include"String.h"
ostream& operator<<(ostream& os, const String& str)
{
return os << str.get_str();
}
int main()
{
String s1("hello");
String s2("world");
String s3(s2);
cout << s3 << endl;
s3 = s1;
cout << s3 << endl;
cout << s2 << endl;
cout << s1 << endl;
system("pause");
return 0;
}
运行结果: