Cpp / std::string 实现

一、答案

#include <iostream>
#include <string.h>
#include <assert.h>

class String
{
public:
    String(const char *str = nullptr);
    String(const String &other);
    ~String(void);
    String &operator=(const String &other);
    bool operator==(const String &str);

    char *Stringcpy(char *dst, const char *src);
    friend std::ostream &operator<<(std::ostream &o, const String &str);

private:
    char *m_data;
};

String::String(const char *str)
{
    if (str == nullptr)
    {
        m_data = new char[1];
        *m_data = '\0';
    }
    else
    {
        int len = strlen(str);
        m_data = new char[len + 1];
        Stringcpy(m_data, str);
    }
}
String::~String(void)
{
    delete[] m_data;
}

String::String(const String &other)
{
    int len = strlen(other.m_data);
    m_data = new char[len + 1];
    Stringcpy(m_data, other.m_data);
}
char *String::Stringcpy(char *dst, const char *src)
{
    assert(dst != nullptr);
    assert(src != nullptr);
    char *ret = dst;
    while ((*dst++ = *src++) != '\0')
        ;
    return ret;
}
String &String::operator=(const String &other)
{
    if (this == &other)
        return *this;
    String tmp(other);
    char *p = tmp.m_data;
    tmp.m_data = m_data;
    m_data = p;
    return *this;
}

bool String::operator==(const String &str)
{
    return strcmp(m_data, str.m_data) == 0;
}

std::ostream &operator<<(std::ostream &o, const String &str)
{
    o << str.m_data;
    return o;
}

int main()
{
    String s = "hello";
    String s2 = s;
    String ss = "hello";
    std::cout << "s = " << s << std::endl;
    std::cout << "s2 = " << s2 << std::endl;
    std::cout << std::boolalpha << (ss == s) << std::endl;
    return 0;
}

二、其他

这里面有个考点,就是赋值构造函数的写法。传统的写法可能如下:

String &String::operator=(const String &other)
{
    if (this == &other)
        return *this;

    delete[] m_data;

    int len = strlen(other.m_data);
    m_data = new char[len + 1];
    Stringcpy(m_data, other.m_data);

    return *this;
}

这种写法能够很好的完成功能,但是问题在于如果 new char 时如果系统内容不足的话就会抛出异常,此时因为上一句代码已经将 m_data 释放掉了,所以此时的 String 实例就是异常的。就算外面已经做好异常处理,String 实例已经是不能再用的了。

解决这个问题的方案可以是将 new char 放置到 delete 的前面,这样就算抛出了异常也不会造成 String 实例的异常。

另外一种方案就是上面答案中的方法,巧妙的是不仅可以解决上述问题,还可以通过临时变量退出当前上下文时自动释放内存的方式释放掉之前的字符串。

 

参考:https://blog.csdn.net/qq_31558353/article/details/50788843

 

(SAW:Game Over!)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值