Skip to content

【实战】实现一个简单的String类

一、确定需求

需要实现如下功能

  • 实现构造函数
  • 实现析构函数
  • 实现复制构造函数
  • 实现赋值操作符
  • 实现字符串连接
  • 实现相等判断
  • 实现取子字符串
  • 实现求字符串长度
  • 实现字符串流式输出

二、代码

  • MString.h 头文件
cpp
#pragma once
#include <cstring> // C 语言字符串库
#include <ostream>

namespace Mer
{
    class MString
    {
    public:
        MString(const char* str = nullptr);
        MString(char* str); // 构造函数
        MString(const MString& str); // 复制构造函数
        ~MString(); // 析构函数

        MString operator+(const MString& str); // 字符串连接
        MString& operator=(const MString& str); // 赋值操作运算符
        bool operator==(const MString& str); // 相等判断

        int length() const; // 字符串长度
        MString substr(int start, int n); // 获取字串
        friend std::ostream& operator<<(std::ostream& out, const MString& str); // 流式输出

    private:
        char* mData = nullptr; // 字符串首地址指针
        int mSize = 0; // 字符串长度
    };
}
  • MString.cpp 源文件
cpp
#include "MString.h"
#include <cassert>


namespace Mer
{
    MString::MString(const char* str)
    {
        if (str == nullptr)
        {
            mData = new char[1];
            mData[0] = '\0';
            mSize = 0;
        }
        else
        {
            mSize = strlen(str);
            mData = new char[mSize + 1];
            strcpy(mData, str);
        }
    }

    MString::MString(char* str)
    {
        if (str == nullptr)
        {
            mData = new char[1];
            mData[0] = '\0';
            mSize = 0;
        }
        else
        {
            mSize = strlen(str);
            mData = new char[mSize + 1];
            strcpy(mData, str);
        }
    }

    MString::MString(const MString& other) // 复制构造函数
    {
        mSize = other.mSize;
        mData = new char[mSize + 1];
        strcpy(mData, other.mData);
    }

    MString::~MString() // 析构函数
    {
        mSize = 0;
        delete[] mData;
        mData = nullptr;
    }

    MString MString::operator+(const MString& other) // 字符串连接
    {
        MString newStr;
        delete[] newStr.mData; // 删除空白字符串的原有内容'\0'
        newStr.mSize = this->mSize + other.mSize;
        newStr.mData = new char[newStr.mSize + 1];
        strcpy(newStr.mData, this->mData);
        strcpy(newStr.mData + this->mSize, other.mData);
        return newStr;
    }

    MString& MString::operator=(const MString& other) // 赋值操作运算符
    {
        if (this == &other) // 检查自赋值
        {
            return *this;
        }
        delete[] mData; // 释放原有内存
        mSize = other.mSize;
        mData = new char[mSize + 1];
        strcpy(mData, other.mData);
        return *this;
    }

    bool MString::operator==(const MString& other) // 相等判断
    {
        return (mSize == other.mSize) && (strcmp(mData, other.mData) == 0);
    }

    int MString::length() const// 字符串长度
    {
        assert(mSize == strlen(mData));
        return mSize;
    }

    MString MString::substr(int start, int n) // 获取字串
    {
        assert(n <= mSize);
        MString newStr;
        delete[] newStr.mData;
        newStr.mSize = n;
        newStr.mData = new char[n + 1];
        for (int i = 0; i < n; ++i)
        {
            if (start + i < mSize)
                newStr.mData[i] = mData[start + i];
            else
                newStr.mData[i] = NULL;
        }
        newStr.mData[n] = '\0';
        return newStr;
    }

    std::ostream& operator<<(std::ostream& out, const MString& str) // 流式输出
    {
        out << str.mData;
        return out;
    }

}

三、测试

  • main.cpp 源文件
cpp
#include <iostream>
#include <cassert>
#include "MString.h"

int main()
{
    Mer::MString goodStr("Good");
    assert(goodStr.length() == strlen("Good"));

    Mer::MString jobStr("Job!");
    std::cout << goodStr.substr(0, 4) << std::endl;

    Mer::MString goodJob(goodStr + jobStr);
    std::cout << goodJob << std::endl;

    char* testStr = new char[10];
    strcpy(testStr, "Nice");
    std::cout << testStr << std::endl;

    Mer::MString niceStr(testStr);
    delete[] testStr;
    std::cout << niceStr << std::endl;

    Mer::MString nice2Str(niceStr);
    assert(nice2Str == niceStr);

    return 0;
}

上次更新于: