MyString.h
#ifndef __MYSTRING_H_
#define __MYSTRING_H_
#include <stdlib.h>
#include <iostream>
#include <cstring>
using namespace std;
class MyString
{
// 重载 <<
// 最好是 const 的,可以输出匿名变量(匿名变量不能被非 const 的左值引用接收)
friend ostream& operator<<(ostream &os, const MyString &s);
// 重载 >>
friend istream& operator>>(istream &is, MyString &s);
private:
// 字符串的有效长度
int m_len;
// 字符串指针
char* m_pStr;
public:
MyString();
MyString(const char *);
MyString(const MyString &);
~MyString();
// 重载 =
MyString& operator=(const MyString &);
// 重载 []
char& operator[](int index);
// 重载 +
MyString operator+(const MyString &);
// 重载 +=
MyString& operator+=(const MyString &);
// 重载 ==
bool operator==(const MyString &);
// 重载 !=
bool operator!=(const MyString &);
};
#endif
MyString.cpp
#include "MyString.h"
ostream& operator<<(ostream &os, const MyString &s){
os << s.m_pStr;
return os;
}
istream& operator>>(istream &is, MyString &s){
char temp[4096] = {0};
is >> temp;
if (s.m_pStr != NULL)
{
s.m_len = 0;
free(s.m_pStr);
s.m_pStr = NULL;
}
s.m_len = strlen(temp);
s.m_pStr = (char*)malloc(s.m_len);
strcpy(s.m_pStr, temp);
return is;
}
MyString::MyString()
{
m_len = 0;
m_pStr = NULL; // 注意 '\0' NULL ""的区别
}
MyString::MyString(const char *c)
{
if (c != NULL)
{
m_len = strlen(c);
m_pStr = (char*)malloc(m_len + 1);
strcpy(m_pStr, c);
}
cout << "MyString(const char *c)..." << endl;
}
MyString::MyString(const MyString &s)
{
if (s.m_pStr != NULL)
{
m_len = s.m_len;
m_pStr = (char*)malloc(m_len + 1);
strcpy(m_pStr, s.m_pStr);
}
cout << "MyString(const MyString &s)..." << endl;
}
MyString::~MyString()
{
m_len = 0;
if (m_pStr != NULL)
{
free(m_pStr);
m_pStr = NULL;
}
cout << "~MyString()..." << endl;
}
MyString& MyString::operator=(const MyString &s)
{
cout << "operator=(const MyString &s)..." << endl;
// 1. 是否是给自身赋值
if (this == &s)
{
return *this;
}
// 2. 处理自身垃圾
if (m_pStr != NULL)
{
free(m_pStr);
m_pStr = NULL;
}
// 3. 深拷贝
if (s.m_pStr != NULL)
{
m_len = s.m_len;
m_pStr = (char*)malloc(m_len + 1);
strcpy(m_pStr, s.m_pStr);
}
// 4. 返回自身
return *this;
}
char& MyString::operator[](int index)
{
if (m_len == 0)
{
throw "bad memory";
}
if (index < 0 || index >= m_len)
{
throw "out of range";
}
return m_pStr[index];
}
MyString MyString::operator+(const MyString &s)
{
// 方式一:
/*
MyString temp;
temp.m_len = m_len + s.m_len;
temp.m_pStr = (char*)malloc(temp.m_len + 1);
// memset(temp.m_pStr, 0, temp.m_len + 1);
strcpy(temp.m_pStr, m_pStr); // 注意 strcpy 和 strcat 的使用
strcat(temp.m_pStr, s.m_pStr); // 注意 strcat 的使用
return temp;
*/
// 方式二:
MyString temp = *this;
return temp += s;
}
MyString& MyString::operator+=(const MyString &s)
{
if (s.m_len > 0)
{
// 处理自身垃圾
if (m_pStr != NULL)
{
char* pTemp = m_pStr;
m_len += s.m_len;
m_pStr = (char*)malloc(m_len + 1);
strcpy(m_pStr, pTemp);
strcat(m_pStr, s.m_pStr);
free(pTemp);
pTemp = NULL;
}
}
return *this;
}
bool MyString::operator==(const MyString &s)
{
if (m_len == 0 || s.m_len == 0)
{
return false;
}
if(m_len != s.m_len)
{
return false;
}
for (int i = 0; i < m_len; i++)
{
if (m_pStr[i] != s.m_pStr[i])
{
return false;
}
}
return true;
}
bool MyString::operator!=(const MyString &s)
{
return !(*this == s);
}
test.cpp
#include <iostream>
#include "MyString.h"
using namespace std;
int main(){
// 隐式转换
MyString s0 = "123";
cout << s0 << endl;
// 构造函数
MyString s1("abc");
cout << s1 << endl;
// 拷贝构造
MyString s2 = s1;
cout << s2 << endl;
// 拷贝构造
MyString s3(s2);
cout << s3 << endl;
// = 操作符
s3 = s1;
cout << s3 << endl;
// [] 操作符
cout << s3[1] << endl;
s3[1] = '1';
cout << s3 << endl;
// + 操作符
cout << s1 + s2 +s3 << endl;
// += 操作符
s3 += s1;
cout << s3 << endl;
// == 操作符
cout << (s3 == s1) << endl;
// != 操作符
cout << (s3 != s1) << endl;
return 0;
}
输出:
MyString(const char *c)...
abc
MyString(const MyString &s)...
abc
MyString(const MyString &s)...
abc
operator=(const MyString &s)...
abc
b
a1c
abcabca1c
~MyString()...
~MyString()...
a1cabc
0
1
~MyString()...
~MyString()...
~MyString()...