string类成员函数的自我实现

本文详细介绍了如何使用C++实现一个可变大小的String类,包括无参、有参构造函数,拷贝构造函数,析构函数,以及成员函数如at(), empty(), capacity(), length(), expand(), resize(), 和各种赋值与连接操作。着重展示了字符串初始化、内存管理以及异常处理的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

string类成员函数的自我实现

#include <iostream>
#include <cstring>
using namespace std;

class String
{
public:
    String() //无参构造
    {
        m_str = new char[16];
        cap = 15;
    }
    String(const char *str);                     //有参构造函数
    String(int n, char c);                       //有参构造函数
    String(const String &str);                   //拷贝构造函数
    ~String();                                   //析构函数
    const char &at(int n);                       //会进行异常检查(越界检查)
    bool empty() const;                          //判断字符串是否为空
    int capacity() const { return cap; }         //返回容量
    int length() const { return strlen(m_str); } //返回字符串大小
    void expand(int n);                          //扩充容量
    void resize(int len, char c);                //将字符串大小置为 len,并用字符c填充不足部分

    String &assign(const String &s);                 //将字符串s赋值给当前字符串
    String &assign(const String &s, int n);          //将s字符串从第i个字符开始拷贝给当前字符串
    String &assign(const String &s, int n, int len); //将s字符串从第i个字符开始拷贝n个字符给当前字符串

    String &append(const char *s);                   //将字符串s连接到当前字符串结尾
    String &append(const String &s, int len);        //将字符串s的前n个字符连接到当前字符串结尾
    String &append(const String &s, int n, int len); //将字符串s从n开始的len个字符连接到当前字符串结尾

    int find(char c, int pos); //从pos开始查找字符C在当前字符串的位置

    String substr(int start, int n) const; //裁剪
    void swap(String &s);                  //交换对象

    friend ostream &operator<<(ostream &os, const String &s1); //重载输入流<<
    friend istream &operator>>(istream &is, String &str);      //重载输出流>>
    String &operator=(const String &str);                      //重载运算符=
    bool operator==(String &s);                                //重载运算符==
    bool operator!=(String &s);                                //重载运算符!=
    char operator[](int n);                                    //重载[]

private:
    char *m_str;
    int cap;
};

String::String(const char *str)
{
    if (strlen(str) <= 15)
    {
        cap = 15;
        m_str = new char[16];
    }
    else
    {
        cap = strlen(str) + 1;
        m_str = new char[cap];
    }
    strcpy(m_str, str);
}

String::String(int n, char c)
{
    if (n <= 15)
    {
        cap = 15;
        m_str = new char[16];
    }
    else
    {
        cap = n + 1;
        m_str = new char[cap];
    }

    for (int i = 0; i < n; i++)
    {
        m_str[i] = c;
    }
    m_str[n] = '\0';
}

String::String(const String &str) : m_str(NULL)
{
    if (strlen(str.m_str) <= 15)
    {
        cap = 15;
        m_str = new char[16];
    }
    else
    {
        cap = strlen(str.m_str) + 1;
        m_str = new char[cap];
    }
    strcpy(m_str, str.m_str);
}

String::~String()
{
    if (m_str != NULL)
    {
        delete[] m_str;
        m_str = NULL;
    }
}

ostream &operator<<(ostream &os, const String &s1)
{
    os << s1.m_str;
    return os;
}

istream &operator>>(istream &is, String &str)
{
    char tmp[1024];
    cin >> tmp;
    int l1 = strlen(tmp) + 6;
    if (str.cap == 0)
    {
        str.m_str = new char[l1];
    }
    if (str.cap < l1)
    {
        str.expand(l1 - str.cap);
    }
    strcpy(str.m_str, tmp);
    return is;
}

String &String::operator=(const String &str)
{
    if (m_str != nullptr)
    {
        delete[] m_str;
    }
    m_str = new char[str.cap];
    cap = str.cap;
    strcpy(m_str, str.m_str);
}

bool String::empty() const
{
    if (m_str == NULL)
    {
        return true;
    }
    else
    {
        return false;
    }
}

const char &String::at(int n)
{
    if (n > strlen(m_str))
    {
        cout << "超出范围!" << endl;
        return m_str[strlen(m_str)];
    }
    else
    {
        return m_str[n];
    }
}

void String::expand(int n) //扩充容量
{
    cap = cap + n;
    char *str = new char[cap + 1];
    strcpy(str, m_str);
    delete[] m_str;
    m_str = str;
    str = NULL;
}

void String::resize(int len, char c) //将字符串大小置为 len,并用字符c填充不足部分
{
    if (len >= strlen(m_str))
    {
        int temp = strlen(m_str);
        expand(len - temp);
        for (int i = temp; i < len; i++)
        {
            m_str[i] = c;
        }
    }
    else
    {
        char *str = new char[len + 1];
        strcpy(str, m_str);
        delete[] m_str;
        m_str = str;
        str = NULL;
    }
    m_str[len] = '\0';
}

String &String::assign(const String &s) //将字符串s赋值给当前字符串
{
    this->m_str = new char[strlen(s.m_str) + 1];
    strcpy(m_str, s.m_str);
}

String &String::assign(const String &s, int n) //将s字符串从第n个字符开始拷贝给当前字符串
{
    int len = strlen(s.m_str) - n;
    m_str = new char[len + 1];
    for (int j = 0; j < len + 1; j++)
    {
        m_str[j] = s.m_str[n + j];
    }
    m_str[len] = '\0';
}

String &String::assign(const String &s, int n, int len) //将s字符串从第i个字符开始拷贝n个字符给当前字符串
{
    m_str = new char[len + 1];
    for (int j = 0; j < len + 1; j++)
    {
        m_str[j] = s.m_str[n + j];
    }
    m_str[len] = '\0';
}

String &String::append(const char *s) //将字符串s连接到当前字符串结尾
{
    int i = strlen(m_str);
    int len = strlen(s);
    expand(len);
    for (int j = 0; j < len; j++)
    {
        m_str[i + j] = s[j];
    }
    m_str[i + len] = '\0';
}

String &String::append(const String &s, int len) //将字符串s的前len个字符连接到当前字符串结尾
{
    int i = strlen(m_str);
    if (len > strlen(s.m_str))
        len = strlen(s.m_str);
    expand(len);
    for (int j = 0; j < len; j++)
    {
        m_str[i + j] = s.m_str[j];
    }
    m_str[i + len] = '\0';
}

String &String::append(const String &s, int n, int len) //将字符串s从n开始的len个字符连接到当前字符串结尾
{
    int i = strlen(m_str);
    if ((len + n) > strlen(s.m_str))
        len = strlen(s.m_str) - n;
    expand(len);
    for (int j = 0; j < len; j++)
    {
        m_str[i + j] = s.m_str[j + n];
    }
    m_str[i + len] = '\0';
}

int String::find(char c, int pos = 0) //从pos开始查找字符C在当前字符串的位置
{
    int n = 0;
    int len = strlen(m_str);
    for (int i = pos; i < len; i++)
    {
        if (c == m_str[i])
        {
            n = i + 1;
            return n;
        }
    }
    if (n == 0)
    {
        cout << "未在当前字符串中发现该字符!" << endl;
    }
}

String String::substr(int start, int n) const
{
    String s1;
    s1.assign(*this, start, n);
    return s1;
}

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

bool String::operator!=(String &s)
{
    if (strcmp(this->m_str, s.m_str) == 0)
    {
        return false;
    }
    else
    {
        return true;
    }
}

void String::swap(String &s) //交换对象
{
    char *temp = m_str;
    m_str = s.m_str;
    s.m_str = temp;

    int count = cap;
    cap = s.cap;
    s.cap = count;
}

char String::operator[](int n)
{
    return *(m_str + n);
}

int main() //测试函数
{
    String s1;
    s1 = "helloworld!";
    cout << s1 << endl;
    cout << s1.empty() << endl;    //判断字符串是否为空
    cout << s1.at(1) << endl;      //at函数会进行异常检查(越界检查)
    cout << s1.length() << endl;   //返回字符串长度
    cout << s1.capacity() << endl; //返回容量

    s1.resize(15, '0'); //扩充到15,以0填充
    cout << s1 << endl;

    String s2;
    s2.assign(s1);
    cout << s2 << endl;

    String s3;
    s3.assign(s1, 5);
    cout << s3 << endl;

    String s4;
    s4.assign(s1, 5, 5);
    cout << s4 << endl;

    s1.append(" vscode");
    cout << s1 << endl;

    s1.append(s4, 0, 5);
    cout << s1 << endl;

    s1.swap(s4);
    cout << s1 << endl;
    cout << s4 << endl;

    s1 = s4.substr(7, 3); //代码的裁剪
    cout << s1 << endl;

    cout << s4.find('o') << endl;

    cout << (s1 == s4) << endl;
    cout << (s1 != s4) << endl;

    cout << s4[3] << endl;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@小高同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值