【C++】 自定义 string 类实现详解

C++ 自定义 string 类实现详解

类定义与成员变量

我们的 stringCap 类包含以下成员变量:

  • _str:指向字符串的指针。
  • _size:字符串的当前长度(不包括终止符)。
  • _capacity:字符串的最大容量(不包括终止符)。
class stringCap {
private:
    char* _str;
    size_t _size;
    size_t _capacity;
    // ...
};

构造与析构

stringCap 提供了多种构造函数,包括默认构造函数、拷贝构造函数、移动构造函数以及从 C 风格字符串构造的构造函数。析构函数负责释放分配给 _str 的内存。

stringCap() : _str(new char[1]), _size(0), _capacity(0) { _str[0] = '\0'; }
stringCap(const char* s);
stringCap(const stringCap& s);
stringCap(stringCap&& s) noexcept;
~stringCap() { delete[] _str; }

容量与大小

capacity()size() 分别返回字符串的最大容量和实际长度。

size_t capacity() const { return _capacity; }
size_t size() const { return _size; }

迭代器

begin()end() 返回指向字符串开始和结束的迭代器,用于遍历字符串。

typedef char* iterator;
iterator begin() { return _str; }
iterator end() { return _str + _size; }

字符串操作

push_back(), append(), clear(), insert(), resize()erase() 等函数用于添加、拼接、清除、插入、调整大小和删除字符串中的字符或子串。

void push_back(char ch);
void append(const char* str);
void clear();
void insert(size_t pos, char ch);
void insert(size_t pos, const char* str);
void resize(size_t n, char ch = '\0');
void erase(size_t pos, size_t len = npos);

查找与替换

find() 函数用于在字符串中查找特定字符或子串的位置。

size_t find(char ch, size_t pos = 0);
size_t find(const char* str, size_t pos = 0);

比较操作

==, !=, <, <=, >>= 运算符用于比较两个 stringCap 对象的内容。

bool operator==(const stringCap& s);
bool operator!=(const stringCap& s);
bool operator<(const stringCap& s);
bool operator<=(const stringCap& s);
bool operator>(const stringCap& s);

输入输出流操作

>><< 运算符重载允许通过 istreamostream 类型的对象读写 stringCap 对象。

istream& operator>>(istream& in, stringCap& s);
ostream& operator<<(ostream& out, const stringCap& s);

完整代码

#include <iostream>
#include <cstring>
#include <cassert>
#include <algorithm> // For std::swap
using namespace std;
namespace cl {

    class stringCap {
    private:
        char* _str;         // 指向字符串的指针
        size_t _size;       // 字符串的有效长度
        size_t _capacity;   // 字符串的最大容量
        static const size_t npos; // 注意这里声明了静态成员

        // 私有辅助函数,用于重新分配内存
        void reserve(size_t newCapacity) {
            assert(newCapacity >= _size); // 确保新容量大于等于当前字符串长度
            char* tmp = new char[newCapacity + 1];
            strcpy(tmp, _str);            // 复制原字符串
            delete[] _str;                // 释放原内存
            _str = tmp;
            _capacity = newCapacity;
        }

    public:
        // 默认构造函数
        stringCap(const char* s = "") :
            _str(new char[strlen(s) + 1]),
            _size(strlen(s)),
            _capacity(_size)
        {
            strcpy(_str, s);
        }

        // 拷贝构造函数
        stringCap(const stringCap& s) {
            _size = s._size;
            _capacity = s._capacity;
            _str = new char[_capacity + 1];
            strcpy(_str, s._str);
        }

        // 移动构造函数
        stringCap(stringCap&& s) noexcept :
            _str(s._str),
            _size(s._size),
            _capacity(s._capacity)
        {
            s._str = nullptr;
            s._size = s._capacity = 0;
        }

        // 析构函数
        ~stringCap() {
            delete[] _str;
            _str = nullptr;
            _size = _capacity = 0;
        }

        // 迭代器相关
        typedef char* iterator;
        iterator begin() { return _str; }
        iterator end() { return _str + _size; }

        // 获取字符串
        const char* c_str() const { return _str; }

        // 获取容量和大小
        size_t capacity() const { return _capacity; }
        size_t size() const { return _size; }

        // 扩容函数
        void reserve(size_t n) {
            if (n > _capacity) {
                reserve(n);
            }
        }

        // 添加单个字符到末尾
        void push_back(char ch) {
            if (_size == _capacity) {
                reserve(_capacity == 0 ? 4 : _capacity * 2);
            }
            _str[_size] = ch;
            _str[++_size] = '\0';
        }

        // 添加字符串到末尾
        void append(const char* str) {
            size_t len = strlen(str);
            if (_size + len > _capacity) {
                reserve(_size + len);
            }
            strcat(_str, str);
            _size += len;
        }

        // 清空字符串
        void clear() {
            _str[0] = '\0';
            _size = 0;
        }

        // 插入单个字符
        void insert(size_t pos, char ch) {
            assert(pos <= _size);
            if (_size == _capacity) {
                reserve(_capacity == 0 ? 2 : _capacity * 2);
            }
            memmove(_str + pos + 1, _str + pos, _size - pos + 1);
            _str[pos] = ch;
            ++_size;
        }

        // 插入字符串
        void insert(size_t pos, const char* str) {
            assert(pos <= _size);
            size_t len = strlen(str);
            if (_size + len > _capacity) {
                reserve(_size + len);
            }
            memmove(_str + pos + len, _str + pos, _size - pos + 1);
            memcpy(_str + pos, str, len);
            _size += len;
        }

        // 调整字符串大小
        void resize(size_t n, char ch = '\0') {
            if (n < _size) {
                _str[n] = '\0';
                _size = n;
            }
            else {
                if (n > _capacity) {
                    reserve(n);
                }
                memset(_str + _size, ch, n - _size);
                _str[n] = '\0';
                _size = n;
            }
        }

        // 删除子字符串
        void erase(size_t pos, size_t len = stringCap::npos) {
            assert(pos < _size);
            if (len > _size - pos) {
                _str[pos] = '\0';
                _size = pos;
            }
            else {
                memmove(_str + pos, _str + pos + len, _size - pos - len + 1);
                _size -= len;
            }
        }

        // 查找单个字符
        size_t find(char ch, size_t pos = 0) const {
            for (size_t i = pos; i < _size; ++i) {
                if (_str[i] == ch) {
                    return i;
                }
            }
            return npos;
        }

        // 查找字符串
        size_t find(const char* str, size_t pos = 0) const {
            size_t strLen = strlen(str);
            for (size_t i = pos; i <= _size - strLen; ++i) {
                if (strncmp(_str + i, str, strLen) == 0) {
                    return i;
                }
            }
            return npos;
        }

        // 交换函数
        void swap(stringCap& s) {
            std::swap(_str, s._str);
            std::swap(_size, s._size);
            std::swap(_capacity, s._capacity);
        }

        // 下标操作符
        char& operator[](size_t pos) {
            return _str[pos];
        }

        // 赋值操作符
        stringCap& operator=(stringCap s) {
            swap(s);
            return *this;
        }

        // 连接操作符
        stringCap& operator+=(char ch) {
            push_back(ch);
            return *this;
        }

        // 比较操作符
        bool operator==(const stringCap& s) const {
            return strcmp(_str, s._str) == 0;
        }
        bool operator!=(const stringCap& s) const {
            return !(*this == s);
        }
        bool operator<(const stringCap& s) const {
            return strcmp(_str, s._str) < 0;
        }
        bool operator<=(const stringCap& s) const {
            return !(*this > s);
        }
        bool operator>(const stringCap& s) const {
            return s < *this;
        }
    };
    const size_t stringCap::npos = -1; // 静态成员的定义必须放在类外

    // 输入流操作符
    istream& operator>>(istream& in, stringCap& s) {
        in >> std::noskipws; // 不跳过空白字符
        s.clear();           // 清空字符串
        char ch;
        while (in.get(ch)) {
            if (ch == ' ' || ch == '\n') {
                break;
            }
            s.push_back(ch);
        }
        return in;
    }
    // 输出流操作符
    ostream& operator<<(ostream& out, const stringCap& s) {
        out.write(s.c_str(), s.size());
        return out;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值