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()...