class声明
#ifndef __MYSTRING__ // 0.防卫式声明
#define __MYSTRING__
#include <string.h>
#include <iostream>
using std::ostream;
using std::strcpy;
using std::strlen;
class String // 1.class head
{
public:
String(const char* cstr = 0); // 4.基础构造函数,接收一个字符串,不改动原本的所以const,默认值=0,因为常常定义string的时候不设初值
// ps:因为class with pointer,所以需要特别关注三个函数:
String(const String& str); // 5.拷贝构造函数:copy的参考是String,优先&,const因为不改变。
String& operator=(const String& str); // 6.拷贝赋值 重载= :参数考虑同上;为了连续赋值,要return Stirng;返回加&,因为返回的不是local object,是本来就存在的*this。
~String(); // 7.析构函数
char* get_c_str() const { return m_data; } // 8.为了cout重载<<;加函数const,因为不改data。
private:
char* m_data; // 3.字符串大小未知,所以用指针
};
#endif // __MYSTRING__
class成员函数定义
#include "String.h"
inline // 响编译器建议inline
String::String(const char* cstr = 0) {
if (cstr) { // 1.先看有没有传东西
auto len = strlen(cstr);
m_data = new char[len + 1]; // 2.最后有 '\0'
memset(m_data, 0, len+1);
strcpy(m_data, cstr);
}
else { // 未指定初值
m_data = new char[1];
*m_data = '\0';
}
}
inline
String::String(const String& str) {
auto len = strlen(str.m_data); // 直接取另一个的data,因为兄弟之间互为friend
m_data = new char[len + 1];
memset(m_data, 0, len + 1);
strcpy(m_data, str.m_data);
}
inline String&
String::operator=(const String& str) {
if (this == &str) { // 0.自我赋值检测,否则直接delete,没有数据了
return *this;
}
delete[] m_data; // 1.清空被赋值的内容
auto len = strlen(str.m_data);
m_data = new char[len + 1]; // 2.申请新的内存
memset(m_data, 0, len + 1);
strcpy(m_data, str.m_data); // 3.拷贝
return *this;
}
inline
String::~String() // 防止内存泄漏
{
delete[] m_data;
}
inline ostream&
operator<<(ostream& os, const String& str) {
os << str.get_c_str();
return os;
}