算法设计与分析之C++习题

一 参考C++ STL的string类构造一个自定义的字符串类

构造一个自定义的字符串类类似于 C++ 标准库中的 std::string,需要支持字符串的动态分配、拷贝、拼接、访问字符等基本操作。我们可以从构造函数、析构函数、运算符重载、以及常见的字符串操作函数等方面来设计这个类。

1. 基本思路

  • 存储方式:字符串本质是一个字符数组,我们可以用一个指针来存储字符串数据,并通过动态分配内存来管理字符数组。
  • 长度管理:使用一个变量来存储字符串的长度。
  • 内存管理:实现拷贝构造函数、赋值运算符和析构函数以避免内存泄漏和重复分配。
  • 功能实现:添加一些常见的功能,比如字符串拼接、访问单个字符、获取字符串长度等。

2. 代码实现

#include <iostream>
#include <cstring>  // 用于 std::strlen 和 std::strcpy

class MyString {
private:
    char* data;  // 存储字符串数据
    size_t length;  // 存储字符串的长度

public:
    // 默认构造函数
    MyString() : data(nullptr), length(0) {}

    // 带参数的构造函数
    MyString(const char* str) {
        if (str) {
            length = std::strlen(str);  // 获取传入字符串的长度
            data = new char[length + 1];  // 为字符串分配内存(+1 为了放终止符 '\0')
            std::strcpy(data, str);  // 复制字符串数据
        } else {
            data = nullptr;
            length = 0;
        }
    }

    // 拷贝构造函数
    MyString(const MyString& other) {
        length = other.length;
        data = new char[length + 1];  // 分配新的内存
        std::strcpy(data, other.data);  // 复制字符串数据
    }

    // 移动构造函数 (C++11)
    MyString(MyString&& other) noexcept : data(other.data), length(other.length) {
        other.data = nullptr;  // 转移所有权,防止双重释放
        other.length = 0;
    }

    // 析构函数
    ~MyString() {
        delete[] data;  // 释放内存
    }

    // 赋值运算符重载 (拷贝赋值)
    MyString& operator=(const MyString& other) {
        if (this == &other) {
            return *this;  // 防止自我赋值
        }

        delete[] data;  // 释放当前对象的内存

        length = other.length;
        data = new char[length + 1];  // 分配新内存
        std::strcpy(data, other.data);  // 复制数据

        return *this;
    }

    // 赋值运算符重载 (移动赋值) (C++11)
    MyString& operator=(MyString&& other) noexcept {
        if (this == &other) {
            return *this;
        }

        delete[] data;  // 释放当前对象的内存

        data = other.data;  // 转移所有权
        length = other.length;
        other.data = nullptr;
        other.length = 0;

        return *this;
    }

    // 重载加号运算符,用于字符串拼接
    MyString operator+(const MyString& other) const {
        size_t newLength = length + other.length;
        char* newData = new char[newLength + 1];

        std::strcpy(newData, data);  // 复制第一个字符串
        std::strcat(newData, other.data);  // 拼接第二个字符串

        MyString newString(newData);  // 构造新字符串对象
        delete[] newData;  // 释放临时的内存
        return newString;
    }

    // 获取字符串长度
    size_t size() const {
        return length;
    }

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

    // 重载 [] 操作符,访问字符
    char& operator[](size_t index) {
        if (index >= length) {
            throw std::out_of_range("Index out of range");
        }
        return data[index];
    }

    const char& operator[](size_t index) const {
        if (index >= length) {
            throw std::out_of_range("Index out of range");
        }
        return data[index];
    }

    // 输出流重载,用于打印字符串
    friend std::ostream& operator<<(std::ostream& os, const MyString& str) {
        os << str.data;
        return os;
    }
};

int main() {
    MyString str1("Hello");
    MyString str2(" World!");

    MyString str3 = str1 + str2;  // 拼接字符串
    std::cout << "Concatenated string: " << str3 << std::endl;  // 输出 Hello World!

    str1[0] = 'h';  // 修改字符
    std::cout << "Modified str1: " << str1 << std::endl;  // 输出 hello

    return 0;
}

3. 代码解释

(1) 构造函数与析构函数
  • 默认构造函数:构造一个空字符串(即 data 指向 nullptr)。
  • 带参数的构造函数:根据传入的 C 风格字符串初始化 MyString 对象。
  • 拷贝构造函数:深拷贝,确保两个对象拥有独立的字符串内存。
  • 移动构造函数:将另一个对象的资源“转移”给当前对象,避免不必要的内存分配和释放。
  • 析构函数:释放动态分配的内存。
(2) 赋值运算符重载
  • 拷贝赋值:确保在赋值时进行深拷贝,并处理自我赋值的情况。
  • 移动赋值:通过移动语义实现高效的资源转移,避免重复分配内存。
(3) + 运算符重载

实现字符串拼接,将两个字符串连接成一个新字符串,并返回新的 MyString 对象。

(4) [] 运算符重载

允许通过索引访问或修改字符串中的单个字符,同时处理索引越界的情况。

(5) size()c_str() 方法
  • size():返回字符串的长度。
  • c_str():返回 C 风格字符串(即 char*),方便与 C 库函数交互。
(6) 输出流运算符重载

重载 << 运算符,使得 MyString 对象可以通过标准输出流 std::cout 输出。

4. 总结

这个自定义的 MyString 类提供了基本的字符串操作功能,包括动态内存管理、字符串拼接、字符访问、以及支持移动语义。它与 C++ STL 中的 std::string 类有类似的功能,但实际应用中 std::string 已经过高度优化ÿ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值