前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自实现 MyString 类

自实现 MyString 类

作者头像
我与梦想有个约会
发布2023-10-20 16:52:39
1590
发布2023-10-20 16:52:39
举报
文章被收录于专栏:jiajia_deng

自实现 myString 类主要目的是剖析系统内部的 string 类的一些实现方法以及加强对类封装、运算符重载等特性的掌握。其中包含了几项非常重要的功能实现。

  1. 使用构造器创建对象。
  2. 拷贝构造器创建对象。
  3. 赋值运算符重载构造对象。
  4. []运算符重载构造对象数组。
  5. ==运算符重载判断对象是否相等。
  6. +运算符重载实现对象相加。
  7. >> << 流输入输出运算符实现打印和输入。

具体的实现代码分三个部分,一个 MyString.h 文件,包含类的声明和结构。一个 MyString.cpp 文件,包含类的成员及友元函数实现。最终是一个 main.cpp 来测试我们自己的 MyString 类是否可以正常使用。

【myString.h】

代码语言:javascript
复制
#pragma once
#include <iostream>

class CMyString
{
public:
    // 构造器
    CMyString(char* str = NULL);
    // 拷贝构造器原型,another为传递进来的同类对象
    CMyString(const CMyString & another);
    // 赋值运算符重载,系统会提供默认,但同样是等位拷贝
    CMyString& operator=(const CMyString & another);
    // []运算符重载
    char operator[](int idx);
    // ==运算符重载
    bool operator==(const CMyString& another);
    // + 运算符重载
    CMyString operator+(const CMyString& another);
    // 流输入输出
    friend std::ostream& operator<<(std::ostream& os, CMyString& another);
    friend std::istream& operator<<(std::istream& is, CMyString& another);

    ~CMyString(void);
    char* c_str();
private:
    char* m_str;
};

【myString.cpp】

代码语言:javascript
复制
#include "MyString.h"
#include <cstring>


CMyString::CMyString(char* str)
{
    if (str)
    {
        int len = strlen(str);
        m_str = new char[len + 1];
        strcpy_s(m_str, len + 1, str);
    }
    else
    {
        m_str = new char[1];
        *m_str = '\0';
    }
}

CMyString::CMyString(const CMyString & another)
{
    // 浅拷贝,等位拷贝,会造成 double free
    // 这样操作会导致 m_str 和 another.m_str 指向同一块堆内存
    // 析构时会造成 delete 了同一块内存
    // m_str = another.m_str;

    // 深拷贝,根据another.m_str的长度给对象new一块内存使双方不冲突
    int len = strlen(another.m_str);
    m_str = new char[len + 1];
    strcpy_s(m_str, len + 1, another.m_str);
}

CMyString& CMyString::operator=(const CMyString & another)
{
    if (this == &another)
    {
        // 解决 s6 = s6 会导致崩溃的问题
        return *this;
    }
    delete [] m_str;
    int len = strlen(another.m_str);
    m_str = new char[len + 1];
    strcpy_s(m_str, len + 1, another.m_str);
    return *this;
}

char CMyString::operator[](int idx)
{
    return m_str[idx];
}

bool CMyString::operator==(const CMyString& another)
{
    if (strcmp(this->m_str, another.m_str) == 0)
        return true;
    else
        return false;
}

CMyString CMyString::operator+(const CMyString& another)
{
    int len = 0;
    len = strlen(this->m_str);
    len += strlen(another.m_str);

    CMyString tmp;
    delete [] tmp.m_str;

    tmp.m_str = new char[len + 1];
    memset(tmp.m_str, 0, len + 1);
    strcat_s(tmp.m_str, len + 1, this->m_str);
    strcat_s(tmp.m_str, len + 1, another.m_str);

    return tmp;
}

std::ostream& operator<<(std::ostream& os, CMyString& another)
{
    os << another.m_str;
    return os;
}

std::istream& operator<<(std::istream& is, CMyString& another)
{
    // 先删除了原来保存的数据
    delete [] another.m_str;
    char buffer[BUFSIZ];
    is.getline(buffer, BUFSIZ);
    int length = strlen(buffer);
    another.m_str = new char[length + 1];
    strcpy_s(another.m_str, length + 1, buffer);
    return is;
}

CMyString::~CMyString(void)
{
    std::cout << "delete [] m_str : " << m_str << std::endl;
    delete [] m_str;
}

char* CMyString::c_str()
{
    return m_str;
}

【main.cpp】

代码语言:javascript
复制
#include <iostream>
#include "MyString.h"

using namespace std;

int main(int argc, char* argv[])
{
    // 构造函数,无参数
    CMyString s;
    cout << s.c_str() << endl;

    // 构造函数,有参数
    CMyString s1("china");
    cout << s1.c_str() << endl;

    // 类型转化函数
    CMyString s2 = "china";
    cout << s2.c_str() << endl;

    /*
     以上均是调用构造器来创建的
     */

    // 拷贝构造器
    CMyString s3(s2);
    cout << s3.c_str() << endl;

    // 同上
    CMyString s4 = s3;
    cout << s4.c_str() << endl;

    // 赋值,=号运算符重载
    CMyString s5;
    // 等同于 s5.operator= (s4);
    s5 = s4;
    // 同上 相当于s5.operator=(s4.operator=(s3));
    s5 = s4 = s3;
    cout << s5.c_str() << endl;

    CMyString s6("china");
    // 这样操作会进入=号运算符重载的函数内
    // 但刚进入后 s6 就被 delete 了
    // 如果继续后面的操作将会导致访问违规内存而报错
    // 个别系统环境下可能不报错,带不代表就是正确的
    s6 = s6;
    cout << s6.c_str() << endl;

    // []运算符重载
    cout << s6[2] << endl;

    // ==运算符重载
    if (s5 == s6) cout << "s5 == s6" << endl;

    // + 运算符重载
    CMyString s7 = s6 + s5;
    cout << s7.c_str() << endl;

    cout << s7 << endl;

    getchar();
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-05-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 【myString.h】
  • 【myString.cpp】
  • 【main.cpp】
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档