string类的实现

一,目标
此次目的很明显,实现string类中的主要方法,包括:构造函数,拷贝构造函数,+,+=运算符的重载等。
在实际的面试中,关于string的问题会很多,因此自己实现一遍很有必要。

二,代码实现
1,首先看声明

#pragma once
#include<iostream>
using namespace std;

class MyString
{
    MyString(const char* s = NULL);  //普通构造函数
    MyString(const MyString& x); //拷贝构造函数
    inline size_t Size() const  //获得str长度
    {
        return strlen(str);
    }
    MyString& operator=(const MyString& other); //赋值运算符重载
    MyString operator+(const MyString& x); 
    MyString& operator+=(const MyString& x);
    bool operator==(const MyString& x);
    friend ostream& operator<<(ostream& out, const MyString& x); //<<的重载
    ~MyString();
private:
    char* str;
};

2,具体实现

//如果x==NULL,则申请一个字节用来存放结束符,之所以这样做,是担心直接cout一个NULL的str
MyString::MyString(const char* x)
{
    if (x == NULL)
    {
        str = new char[1];
        *str = '\0';
    }
    else
    {
        str = new char[strlen(x) + 1];  //此处加1是为了放上结束符
        strcpy(str, x);
    }
}

MyString::MyString(const MyString& x)
{
    str = new char[strlen(x.str) + 1];
    strcpy(str, x.str);
}
//这里之所以要检测是否自赋值是因为如果不检测,直接将原始的str清空后,就没办法再给自己复制了
//因为它们指向同一块区域
MyString& MyString::operator=(const MyString& other)
{
    if (this == &other)  //防止自赋值
        return *this;
    delete[] str;
    str = new char[strlen(other.str) + 1];
    strcpy(str, other.str);
}

MyString MyString::operator+(const MyString& x)
{
    MyString temp;
    temp.str = new char[strlen(str) + strlen(x.str) + 1];
    strcpy(temp.str, str);
    strcat(temp.str, x.str);
    return temp;
}
MyString& MyString::operator+=(const MyString& x)
{
    //+=,此时可以调用已重载的+运算符
    *this = *this + x;
    return *this;
}

bool MyString::operator==(const MyString& x)
{

    return strcmp(str, x.str) == 0 ? true : false;
}

ostream& operator<<(ostream& out, const MyString& x)
{
    out << x.str;
    return out;
}

MyString::~MyString()
{
    delete[] str;  //直接删除
}

3,测试代码

void test()
{
   //首先会调用拷贝构造函数,给字符串“hello”创建一个临时对象,然后再掉用赋值运算符给x赋值
    MyString x("hello");
    //调用拷贝构造函数,也可以写为:MyString y(x);
    MyString y = x;
    cout << y << endl;
    MyString z = ",world!";
    //调用+运算符,先产生一个x与z的临时对象,然后调用拷贝构造函数给z赋值,析构临时对象,
    z = x + z;
    cout << z << endl; 
}

注意以上运行还不会成功,需要加入指令:#pragma warning(disable:4996)
这是因为c++认为strcpy等函数不安全,所以已经选择弃用,加入这句指令,就是指忽略相应
的警告。

3,运行结果

注意此处的调试信息在上面的代码中并没有添加,只是为了测试我的猜想
测试是从z的定义那里产生的,
3.1,首先调用构造函数,用字符串给z赋值
3.2 调用加号运算符,生成temp的临时对象,使我不解的是此处为什么没有调用构造函数呢?
然后调用拷贝构造函数生成temp的拷贝对象返回,接着析构temp;
3.3,接着调用等号运算符,把这个拷贝对象再赋给z;
3.4,析构z,x,y

4,总结
1,其实还有很多string类的功能没有实现,以我的理解,只要理解了底层的实现细节,对自己以后使用相应的方法是很有帮助的,毕竟是自己完成过

2,to_str()方法其实就是直接返回 (const char*) str;

3,拷贝构造函数与=构造函数的不同便是,拷贝构造函数是一种特殊的构造函数,所以它是用来初始化一个对象的,而=运算符则是用来给一个已经存在的对象重新赋值

4,每个类都提供了默认的构造函数,拷贝构造函数,析构函数,=运算符,之所以还要自己重新定义,这就设计浅拷贝与深拷贝的问题了,关于这点,有兴趣的可以自己去了解

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值