c++ string的简单实现

string的简单实现

#include <string>
#include <iostream>

using namespace std;

/*
 *  todo
 *  1. copy on write
 * */

class String {
public:
    using size_type = size_t;
    using value_type = char;
    using pointer = char *;

    //有参构造
     String(const char *src = nullptr) {
        init();
        if (nullptr == src) {
            return;
        }
        size_type sz = strlen(src);
        rep.Long = false;
        add(src, sz);
    }

    //拷贝
    String(const String &s) {
        copy(s);
    }

    //移动
    explicit String(String &&s) {
        rep = s.rep;
        if (s.rep.Long) {
            s.init();
        }
    }

    ~String() {
        destory();
    }

    //赋值
    String &operator=(const String &s) {
        destory();
        init();
        copy(s);
        return *this;
    }

    //赋值
    String &operator=(String &&s)  noexcept {
        destory();
        init();
        rep = s.rep;
        if (s.rep.Long) {
            s.init();
        }
        return *this;
    }

    //左移运算符重载
    friend ostream &operator<<(ostream &os, const String &s) {
        if (s.rep.Long) {
            os << s.rep.m_l.beg_;
        } else {
            os << s.rep.m_s.m_data_;
        }
        return os;
    }

    String &operator+=(const String &right) {
        add(right);
        return *this;
    }

    friend String operator+(const String &left, const String &right);

    //输出大小
    [[nodiscard]] size_t size() const {
        if (rep.Long) {
            return rep.m_l.size_;
        }
        return rep.m_s.size_;
    }

    [[nodiscard]] pointer c_str() const {
        if (rep.Long) {
            return rep.m_l.beg_;
        } else {
            return (pointer) rep.m_s.m_data_;
        }
    }

private:

    void init() {
        rep.Long = false;
        rep.m_s.size_ = 0;
        rep.m_s.m_data_[0] = '\0';
    }

    void add(const String &s) {
        if (s.rep.Long) {
            add(s.rep.m_l.beg_, s.rep.m_l.size_);
        } else {
            add((pointer) s.rep.m_s.m_data_, s.rep.m_s.size_);
        }
    }

    void add(const char *src, int n) {
        if (!rep.Long) {
            if (!rep.m_s.add(src, n)) {
                // 复制原值
                m_rep other = this->rep;
                rep.Long = true;
                int sz = other.m_s.size_;
                rep.m_l.init(sz + n + 1);
                rep.m_l.add((pointer) other.m_s.m_data_, other.m_s.size_);
            }
        }
        if (rep.Long) {
            rep.m_l.add(src, n);
        }
    }

    void destory() {
        if (this->rep.Long) {
            if (rep.Long) {
                rep.m_l.destroy_long();
                init();
            }
        }
    }

    void copy(const String &str) {
        this->rep.Long = str.rep.Long;
        if (!str.rep.Long) {
            this->rep.m_s.copy(str.rep.m_s);
        } else {
            add(str.rep.m_l.beg_, str.rep.m_l.size_);
        }
    }

    // 长字符串
    class m_long {
    public:
        pointer beg_;
        pointer cap_;
        size_type size_;

        void destroy_long() {
            if (nullptr != beg_) {
                delete[] beg_;
                beg_ = nullptr;
            }
        }

        void init(size_type n) {
            beg_ = new value_type[n];
            cap_ = beg_ + n;
            size_ = 0;
        }

        void move(m_long *other) {
            beg_ = other->beg_;
            cap_ = other->cap_;
            size_ = other->size_;
        }

        void copy(m_long *other) {
            for (int i = 0; i < other->size_; i++) {
                beg_[i] = other->beg_[i];
            }
            size_ = other->size_;
        }

        void enlarge(size_type n) {
            size_type room = cap_ - beg_;
            if (room < 1024) {
                room = room * 2 + n;
            } else {
                room += n;
            }
            m_long other;
            other.move(this);

            this->init(room);
            this->copy(&other);

            other.destroy_long();
        }

        void enLargeIfNeed(size_type n) {
            if (cap_ - beg_ < n) {
                enlarge(n);
            }
        }

        void add(const char *str, size_t n) {
            if (nullptr == str || n == 0) {
                return;
            }
            enLargeIfNeed(n);
            strncpy(beg_ + size_, str, n);
            size_ += n;
            beg_[size_] = '\0';
        }
    };

    enum {m_min_cap = (sizeof(m_long) - 1)/sizeof(value_type) > 2 ?
                      (sizeof(m_long) - 1)/sizeof(value_type) : 2};

    // 短字符串
    struct m_short {
        value_type m_data_[m_min_cap];
        unsigned char size_;

        void init(size_type n) {
            size_ = 0;
        }

        bool add(const char *str, size_t n) {
            if (nullptr == str || n == 0) {
                return true;
            }
            if (size_ + n + 1 > m_min_cap) {
                return false;
            }
            strncpy(m_data_ + size_, str, n);
            size_ += n;
            m_data_[size_] = '\0';
            return true;
        }

        void copy(const m_short &other) {
            size_ = other.size_;
            strncpy(this->m_data_, other.m_data_, size_);
            this->m_data_[size_] = '\0';
        }
    };

    struct m_rep {
        bool Long{};
        union {
            m_long m_l;
            m_short m_s;
        };
    };
    m_rep rep;
};

String operator+(const String &left, const String &right) {
    String s;
    s.add(left);
    s.add(right);
    return s;
}


int main() {
    String s1("hello world");
    cout << s1.size() << " " << s1 << endl;

    String s2 = s1;
    cout << s2.size() << " "<< s2 << endl;
    String s3;
    cout << s3.size() << " " << s3 << endl;

    String s;
    s += "abcasdsdsadsdfsadfa fsdfsadas";
    cout << s << endl;
}


输出

在这里插入图片描述

c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds
c++ string的简单实现x x s x x x x x x x xcxxcadds

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值