[C++]实现String类

本文档展示了作者花费两天时间用C++实现的String类,包括构造函数、赋值运算符、成员函数如insert和erase等。讨论了运算符返回类型选择、字符串结束标志以及通过代理类实现读写操作区分的可能性。此外,还提及了使用引用计数和写时拷贝等技术提升效率的计划。
摘要由CSDN通过智能技术生成

参考《数据结构——C++实现(第二版)》科学出版社P119
花了两天的时间大致完整地实现了一遍String。
自己暂时还没有发现错误,如有错误或可以优化改进的地方,欢迎指出!

提醒我自己要注意几个点:

  • 运算符返回引用还是对象?
  • 字符串后面系统会自动加上’\0’作为结束标志

String类还有许多可以改进的地方,比如说运用引用计数写时拷贝等技术提高效率。
如果希望区分operator[]的读和写两种动作。可以运用缓式评估思想,利用proxy class来区分其左值运用和右值运用。
以上这些技术详见《More Effective C++》。

class String {
private:
    char *pval;
    size_t length;
public:
    String() : pval(nullptr), length(0) {}
    String(const String& s);
    String(const char* s);
    String& operator=(const String& s);
    virtual ~String() { delete [] pval; }

    bool isEmpty() const { return length == 0; }
    size_t getLength() const { return length; }
    void swap(String& s);                   //交换两个字符串的内容
    const char* cStr() const;               
    bool insert(const String& s, size_t i); //在位置i之后插入s
    bool erase(size_t p, size_t n);         //删除位置从p开始的后面n个字符(p的取值为0到length-1)

    String operator+(const String& s);
    String& operator+=(const String& s);
    String& operator+=(const char* s);
    bool operator==(const String& s) const;
    bool operator!=(const String& s) const;
    char& operator[](size_t i) const;
    friend ostream& operator<<(ostream& os, String& s);

};

String::String(const String& s) {
    length = strlen(s.pval);
    pval = new char[length + 1];
    strcpy(pval, s.cStr());
}

String::String(const char* s) {
    length = strlen(s);
    pval = new char[length + 1];
    strcpy(pval, s);
    pval[length] = '\0';
}

String& String::operator=(const String& s) {
    if (&s != this) {
        delete [] pval;
        length = strlen(s.cStr());
        pval = new char[length + 1];
        strcpy(pval, s.cStr());
    }
    return *this;
}

const char* String::cStr() const {
    return static_cast<const char*>(pval);
}

bool String::insert(const String& s, size_t i) {
    const char* p = s.cStr();
    if (i < 0 || i >= length) {
        return false;
    }
    size_t len = length + s.length;     //总长度
    length = len;
    char *temp = new char[len + 1];     //临时存放拼接的字符串
    strncpy(temp, pval, i);             //将pval指向的字符串复制给temp,最多复制i个
    temp[i] = '\0';
    strcat(temp, p);                    //将pval前半部分和s拼接起来
    size_t j = i + s.length;               //
    for (size_t k = i; k < length; ++k, ++j) {
        temp[j] = pval[k];
    }
    temp[len] = '\0';
    pval = temp;
    return true;
}

bool String::erase(size_t p, size_t n) {
    if (p < 0 || (p + n) > length) {
        return false;
    }
    size_t len = length - n;
    char *temp = new char[length + 1];
    strcpy(temp, pval);
    delete [] pval;
    pval = new char[len + 1];
    strncpy(pval, temp, p + 1);
    for (size_t i = p + n; i < length; ++i) {
        pval[i - n] = temp[i];
    }
    delete [] temp;
    length -= n;
    return true;
}

String String::operator+(const String& s) {
    const char *cs = s.cStr();
    String str;
    length = length + s.length;
    str.pval = new char[length + 1];
    strcpy(str.pval, pval);
    strcat(str.pval, s.cStr());
    return str;
}

String& String::operator+=(const String& s) {
    char *temp = new char[length + 1];
    strcpy(temp, pval);
    delete [] pval;
    length += s.length;
    pval = new char[length + 1];
    strcpy(pval, temp);
    strcat(pval, s.pval);
    delete [] temp;
    return *this;
}

String& String::operator+=(const char* s) {
    size_t len = 0;
    const char* t = s;
    while(*t != '\0') {
        ++len;
        ++t;
    }
    char *temp = new char[length + 1];
    strcpy(temp, pval);
    delete [] pval;
    length += len;
    pval = new char[length + 1];
    strcpy(pval, temp);
    strcat(pval, s);
    return *this;
}

bool String::operator==(const String& s) const {
    return strcmp(this->cStr(), s.cStr()) == 0;
}

bool String::operator!=(const String& s) const {
    return strcmp(this->cStr(), s.cStr()) != 0;
}

//为了效率,operator[]不用考虑越界处理
char& String::operator[](size_t i) const {
    return pval[i];
}

//最好不要定义在类内,否则cout要写在<<右边
ostream& operator<<(ostream& os, String& s) {
    os << s.pval;
    return os;
}

void String::swap(String& s) {
    using std::swap;
    swap(this->pval, s.pval);
    swap(this->length, s.length);
}

void swap(String& lhs, String& rhs) {
    lhs.swap(rhs);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值