当前位置: 首页 > article >正文

C++ 一个基本的 MyString 实现和分析实践

文章目录

      • 1.需求分析
      • 2.代码实现
      • 3.编译运行

不必要背代码,语法到处都是,但是要熟悉实现逻辑,需求分析,以及对于具体的实现细节进行推敲,比如扩容机制、上下界限等问题的处理。

1.需求分析

  • 构造操作
    1.三个构造:构造函数、(深)拷贝构造函数和移动构造函数。
    2.两个赋值:(深)拷贝赋值运算符和移动赋值运算符。
    3.一个析构:析构函数释放内存,防止内存泄漏。

  • 运算符:
    1.重载 [] 运算符,用于访问字符串中的字符,并提供 const 和非 const 版本。
    2.重载 + 运算符,用于字符串拼接。
    3.重载 == 和 != 运算符用于字符串比较。
    4.重载 << 和 >> 运算符,用于输入输出操作。
    5.重载 =

  • 异常
    1.越界异常

知识点:三个构造、动态内存管理、RAII、深拷贝与移动语义、运算符重载、异常处理等。

2.代码实现

#include <iostream>
#include <cstring>  // For strlen, strcpy, etc.

class MyString {
private:
    char* data;  // Pointer to the dynamically allocated array
    size_t length;  // Length of the string (not including null terminator)

public:
    // Default constructor
    MyString() : data(nullptr), length(0) {}

    // Constructor from C-string
    MyString(const char* str) {
        if (str) {
            length = std::strlen(str);
            data = new char[length + 1];  // Allocate memory for string
            std::strcpy(data, str);  // Copy string into memory
        } else {
            data = nullptr;
            length = 0;
        }
    }

    // Copy constructor (deep copy)
    MyString(const MyString& other) {
        length = other.length;
        if (other.data) {
            data = new char[length + 1];
            std::strcpy(data, other.data);
        } else {
            data = nullptr;
        }
    }

    // Move constructor (no deep copy, just transfer ownership)
    MyString(MyString&& other) noexcept : data(other.data), length(other.length) {
        other.data = nullptr;  // Release ownership of the old string
        other.length = 0;
    }

    // Copy assignment operator (deep copy)
    MyString& operator=(const MyString& other) {
        if (this == &other) {
            return *this;  // Handle self-assignment
        }

        // Free existing memory
        delete[] data;

        // Perform deep copy
        length = other.length;
        if (other.data) {
            data = new char[length + 1];
            std::strcpy(data, other.data);
        } else {
            data = nullptr;
        }

        return *this;
    }

    // Move assignment operator (transfer ownership)
    MyString& operator=(MyString&& other) noexcept {
        if (this == &other) {
            return *this;  // Handle self-assignment
        }

        // Free existing memory
        delete[] data;

        // Transfer ownership
        data = other.data;
        length = other.length;
        other.data = nullptr;
        other.length = 0;

        return *this;
    }

    // Destructor (free the allocated memory)
    ~MyString() {
        delete[] data;
    }

    // Get length of the string
    size_t size() const {
        return length;
    }

    // Overload operator[] to access characters
    char& operator[](size_t index) {
        if (index >= length) {
            throw std::out_of_range("Index out of bounds");
        }
        return data[index];
    }

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

    // Overload operator+ for string concatenation
    MyString operator+(const MyString& other) const {
        MyString newStr;
        newStr.length = length + other.length;
        newStr.data = new char[newStr.length + 1];

        // Copy first string
        std::strcpy(newStr.data, data);

        // Concatenate second string
        std::strcat(newStr.data, other.data);

        return newStr;
    }

    // Overload operator== for string comparison
    bool operator==(const MyString& other) const {
        return std::strcmp(data, other.data) == 0;
    }

    // Overload operator!= for string comparison
    bool operator!=(const MyString& other) const {
        return !(*this == other);
    }

    // Output stream overload (printing the string)
    friend std::ostream& operator<<(std::ostream& os, const MyString& str) {
        if (str.data) {
            os << str.data;
        }
        return os;
    }

    // Input stream overload (reading the string)
    friend std::istream& operator>>(std::istream& is, MyString& str) {
        char buffer[1000];  // Assume max input size
        is >> buffer;
        str = MyString(buffer);  // Use the constructor to assign
        return is;
    }
};

int main() {
    // Example usage of MyString class
    MyString str1("Hello");
    MyString str2(" World");

    // Concatenation
    MyString str3 = str1 + str2;
    std::cout << "Concatenated string: " << str3 << std::endl;

    // Comparison
    if (str1 == MyString("Hello")) {
        std::cout << "str1 is equal to 'Hello'" << std::endl;
    }

    // Assignment
    MyString str4;
    str4 = str3;
    std::cout << "Assigned string: " << str4 << std::endl;

    // Input and Output
    MyString inputStr;
    std::cout << "Enter a string: ";
    std::cin >> inputStr;
    std::cout << "You entered: " << inputStr << std::endl;

    return 0;
}

3.编译运行

[jn@jn build]$ ./a.out
Concatenated string: Hello World
str1 is equal to 'Hello'
Assigned string: Hello World
Enter a string: WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
You entered: WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
[jn@jn build]$

http://www.kler.cn/a/314472.html

相关文章:

  • MybatisPlus入门(十)MybatisPlus-逻辑删除和多记录操作
  • 《C++在金融领域的技术革命:高效、安全与创新的融合》
  • 《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址
  • 如何在算家云搭建Peach-9B-8k-Roleplay(文本生成)
  • 【前端学习指南】Vue computed 计算属性 watch 监听器
  • 【QT】QSS
  • idea中.git文件夹存在但是没有git功能列表
  • 数据集的选取、标注
  • POS共识机制简介
  • 从0到1训练私有大模型技能与应用实现 ,企业急迫需求,抢占市场先机
  • LabVIEW提高开发效率技巧----采用并行任务提高性能
  • Qt优秀开源项目之二十三:QSimpleUpdater
  • 地面站通过SSH连接无人机
  • Vue3中监听器watchEffect的使用
  • Vue使用axios二次封装、解决跨域问题
  • 【go/方法记录】cgo静态库编译以及使用dlv定位cgo崩溃问题
  • 《娱乐至死》
  • BERT模型解读与简单任务实现(论文复现)
  • ChatGPT搭上langchain的知识库RAG应用,效果超预期
  • Vue.js 与 Flask/Django 后端的高效配合指南
  • 动态线程池(五)
  • 【ESP32】ESP-IDF开发 | UART通用异步收发传输器+串口收发例程
  • 深度学习-图像处理篇1.3pytorch神经网络例子
  • 【数据仓库】数据仓库层次化设计
  • vue3(整合版)
  • docker入门总结(附错误处理,持续更新)