C++初阶:模拟实现string类

本文详细介绍了C++中的string类的构造函数、拷贝构造函数、赋值重载、析构函数,以及字符串的容量管理、迭代器、修改操作、元素访问、比较运算符、查找功能、输入流处理和交换方法等关键部分。

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

构造函数:

        //全缺省的构造函数
        string(const char* str = "")//有一个/0
        {
            if (str == nullptr)
            {
                assert(nullptr);
                return;
            }
            _size = strlen(str);
            _capacity = _size;
            _str = new char[_capacity + 1];
            strcpy(_str, str);
        }

拷贝构造函数:

        //传统写法
        string(const string& s)
        {
            _str = new char[_capacity + 1];
            strcpy(_str, s._str);
            _size = s._size;
            _capacity = s._capacity;
        }


        //现代写法
        string(const string& s)
            :_str(nullptr)
            ,_size(0)
            ,_capacity(0)
        {
            string tmp(s._str);
            swap(tmp);
        }

赋值重载:

        //传统写法
        string& operator=(const string& s)
        {
            char* tmp = new char[s._capacity + 1];
            strcpy(tmp,s._str);
            
            delete[] _str;
            _str = tmp;
            _size = s._size;
            _capacity = s._capacity;
            
            return *this;
        }


       //现代写法
        string& operator=(string s)
        {
            swap(s);
            return *this;
        }

析构函数:

        ~string()
        {
            if (_str)
            {
                delete[] _str;
                _str = nullptr;
                _size = _capacity = 0;
            }
        }

Capacity(容量):

        // capacity

        size_t size()const
        {
            return _size;
        }

        size_t capacity()const
        {
            return _capacity;
        }

        bool empty()const
        {
            return _size == 0;
        }

        void resize(size_t n, char c = '\0')
        {
            if (n > _size)
            {
                // 如果newSize大于底层空间大小,则需要重新开辟空间
                if (n > _capacity)
                {
                    reserve(n);
                }
                memset(_str + _size, c, n - _size);
            }
            _str[n] = '\0';
            _size = n;
        }

        void reserve(size_t n)
        {
            // 如果新容量大于旧容量,则开辟空间
            if (n > _capacity)
            {
                char* tmp = new char[n + 1];
                strcpy(tmp, _str);
                
            // 释放原来旧空间,然后使用新空间
                delete[] _str;
                _str = tmp;
                _capacity = n;
            }
        }

Iterators(迭代器):

begin+end

        typedef char* iterator;
        typedef const char* const_iterator;


        iterator begin()
        {
            return _str;
        }

        iterator end()
        {
            return _str + _size;
        }
        const_iterator begin() const
        {
            return _str;
        }
        const_iterator end()const
        {
            return _str + _size;
        }

Modifiers(修改):

            // modify

        void push_back(char c)
        {
            //if (_size == _capacity)
            //{
            //    reserve(_capacity == 0 ? 4 : _capacity * 2);
            //}
            //_str[_size] = c;
            //_size++;
            //_str[_size] = '\0';

            insert(_size, c);
        }

        string& operator+=(char c)
        {
            push_back(c);
            return *this;
        }

        void append(const char* str)
        {
            //size_t len = strlen(str);
            //if (len + _size > _capacity)
            //{
            //    reserve(len + _size);
            //}
            //strcpy(_str + _size, str);
            //_size += len;
            insert(_size, str);
        }

        string& operator+=(const char* str)
        {
            append(str);
            return *this;
        }

        void clear()
        {
            _size = 0;
            _str[_size] = '\0';
        }

        void swap(string& s)
        {
            std::swap(_str, s._str);
            std::swap(_size, s._size);
            std::swap(_capacity, s._capacity);
        }

        string& insert(size_t pos, char c)
        {
            assert(pos <= _size);

            if (_size == _capacity)
            {
                reserve(_capacity == 0 ? 4 : _capacity * 2);
            }
            
            //int end = _size;
            //while (end >=(int)pos)
            //{
            //    _str[end + 1] = _str[end];
            //    --end;
            //}
            //_str[pos] = c;
            //++_size;

            size_t end = _size + 1;
            while (end > pos)
            {
                _str[end] = _str[end - 1];
                end--;
            }
            _str[pos] = c;
            ++_size;

            return *this;
        }

        string& insert(size_t pos, const char* str)
        {
            assert(pos <= _size);
            size_t len = strlen(str);
            if (_size + len > _capacity)
            {
                reserve(_size + len);
            }
            
            size_t end = _size + len;
            //while(end>=pos+len)
            //while(end-(int)len>=(int)pos)
            while (end > pos+len-1)
            {
                _str[end] = _str[end - len];
                --end;
            }
            strncpy(_str + pos, str, len);
            _size+=len;

            return *this;
        }


        // 删除pos位置上的元素,并返回该元素的下一个位置

        string& erase(size_t pos, size_t len)
        {
            assert(pos < _size);
            if (len == std::string::npos || len >= _size - pos)//len+pos>=_size
            {
                _str[pos] = '\0';
                _size = pos;
            }
            else
            {
                strcpy(_str + pos, _str + pos + len);
                _size -= len;
            }
            return *this;
        }

Element access(元素访问):

        // access

        char& operator[](size_t pos)
        {
            assert(pos < _size);

            return _str[pos];
        }

        const char& operator[](size_t pos)const
        {
            assert(pos < _size);

            return _str[pos];
        }

relational operators:
 

       bool operator<(const string& s)
        {
            int ret = strcmp(_str, s._str);
            return ret < 0;
        }

        bool operator<=(const string& s)
        {
            int ret = strcmp(_str, s._str);
            return ret < 0 || ret == 0;
        }

        bool operator>(const string& s)
        {
            int ret = strcmp(_str, s._str);
            return ret > 0;

        }

        bool operator>=(const string& s)
        {
            int ret = strcmp(_str, s._str);
            return ret > 0 || ret == 0;
        }

        bool operator==(const string& s)
        {
            int ret = strcmp(_str,s._str);
            return ret == 0;
        }

        bool operator!=(const string& s)
        {
            int ret = strcmp(_str, s._str);
            return ret != 0;
        }

String operations(字符串操作):

        // 返回c在string中第一次出现的位置

        size_t find(char c, size_t pos = 0) const
        {
            assert(pos < _size);
            for (size_t i = pos; i < _size; i++)
            {
                if (_str[i] == c)
                    return i;
            }
            return std::string::npos;
        }

        // 返回子串s在string中第一次出现的位置

        size_t find(const char* s, size_t pos = 0) const
        {
            assert(pos < _size);
            const char* p = strstr(_str + pos, s);
            if (p)
            {
                return p - _str;
            }
            else
            {
                return std::string::npos;
            }
        }

        //生成子字符串
        //返回一个新构造的对象,其值初始化为此对象的子字符串的副本
        string substr(size_t pos = 0, size_t len = std::string::npos)const
        {
            string sub;
            //if (len == npos || len >= _size-pos)
            if (len >= _size - pos)
            {
                for (size_t i = pos; i < _size; i++)
                {
                    sub += _str[i];
                }
            }
            else
            {
                for (size_t i = pos; i < pos + len; i++)
                {
                    sub += _str[i];
                }
            }
            return sub;
        }


        const char* c_str()const
        {
            return _str;
        }

非成员函数重载:


    ////低效率版本(如果输入数据太多的话,会造成频繁扩容,效率低)
    //istream& operator>>(istream& in, string& s)
    //{
    //    s.clear();
    //    char ch;
    //    //in>>ch;// cin 和 printf 取不到空格和换行这样的分隔符,所以用get()
    //    ch = in.get();
    //    while (ch != ' ' && ch != '\n')
    //    {
    //        s += ch;
    //        ch = in.get();
    //    }
    //    return in;
    //}

    //高效率版本  (一把开空间)
    istream& operator>>(istream& in, string& s)
    {
        s.clear();
        char ch;
        ch = in.get();
        char buff[128];
        size_t i = 0;
        while (ch != ' ' && ch != '\n')
        {
            buff[i++] = ch;
            if (i == 127)
            {
                buff[127] = '\0';
                s += buff;
                i = 0;
            }
            ch = in.get();
        }
        if (i > 0)
        {
            buff[i] = '\0';
            s += buff;
        }
        return in;
    }


    istream& getline(istream& in, string& s)
    {
        s.clear();
        char ch;
        ch = in.get();
        char buff[128];
        size_t i = 0;
        while (ch != '\n')
        {
            buff[i++] = ch;
            if (i == 127)
            {
                buff[127] = '\0';
                s += buff;
                i = 0;
            }
            ch = in.get();
        }
        if (i > 0)
        {
            buff[i] = '\0';
            s += buff;
        }
        return in;
    }


    void swap(string& x, string& y)
    {
        x.swap(y);
    }

完整代码:

#pragma once
#include<assert.h>
#include<iostream>
using namespace std;
namespace xx

{
    class string

    {
        //不用友元函数也行
        //friend ostream& operator<<(ostream& _cout, const bit::string& s);
        //friend istream& operator>>(istream& _cin, bit::string& s);

    public:

        typedef char* iterator;
        typedef const char* const_iterator;

    public:

        //全缺省的构造函数
        string(const char* str = "")//有一个/0
        {
            if (str == nullptr)
            {
                assert(nullptr);
                return;
            }
            _size = strlen(str);
            _capacity = _size;
            _str = new char[_capacity + 1];
            strcpy(_str, str);
        }

        ////传统写法
        //string(const string& s)
        //{
        //    _str = new char[_capacity + 1];
        //    strcpy(_str, s._str);
        //    _size = s._size;
        //    _capacity = s._capacity;
        //}

        //现代写法
        string(const string& s)
            :_str(nullptr)
            ,_size(0)
            ,_capacity(0)
        {
            string tmp(s._str);
            swap(tmp);
        }

        ////传统写法
        //string& operator=(const string& s)
        //{
        //    char* tmp = new char[s._capacity + 1];
        //    strcpy(tmp,s._str);
        //    
        //    delete[] _str;
        //    _str = tmp;
        //    _size = s._size;
        //    _capacity = s._capacity;
        //    
        //    return *this;
        //}

        //现代写法
        string& operator=(string s)
        {
            swap(s);
            return *this;
        }


        ~string()
        {
            if (_str)
            {
                delete[] _str;
                _str = nullptr;
                _size = _capacity = 0;
            }
        }



            //////////////////////////////////////////////////////////////

            // iterator

        iterator begin()
        {
            return _str;
        }

        iterator end()
        {
            return _str + _size;
        }
        const_iterator begin() const
        {
            return _str;
        }
        const_iterator end()const
        {
            return _str + _size;
        }


            /////////////////////////////////////////////////////////////

            // modify

        void push_back(char c)
        {
            //if (_size == _capacity)
            //{
            //    reserve(_capacity == 0 ? 4 : _capacity * 2);
            //}
            //_str[_size] = c;
            //_size++;
            //_str[_size] = '\0';

            insert(_size, c);
        }

        string& operator+=(char c)
        {
            push_back(c);
            return *this;
        }

        void append(const char* str)
        {
            //size_t len = strlen(str);
            //if (len + _size > _capacity)
            //{
            //    reserve(len + _size);
            //}
            //strcpy(_str + _size, str);
            //_size += len;
            insert(_size, str);
        }

        string& operator+=(const char* str)
        {
            append(str);
            return *this;
        }

        void clear()
        {
            _size = 0;
            _str[_size] = '\0';
        }

        void swap(string& s)
        {
            std::swap(_str, s._str);
            std::swap(_size, s._size);
            std::swap(_capacity, s._capacity);
        }

        const char* c_str()const
        {
            return _str;
        }



        /////////////////////////////////////////////////////////////

        // capacity

        size_t size()const
        {
            return _size;
        }

        size_t capacity()const
        {
            return _capacity;
        }

        bool empty()const
        {
            return _size == 0;
        }

        void resize(size_t n, char c = '\0')
        {
            if (n > _size)
            {
                // 如果newSize大于底层空间大小,则需要重新开辟空间
                if (n > _capacity)
                {
                    reserve(n);
                }
                memset(_str + _size, c, n - _size);
            }
            _str[n] = '\0';
            _size = n;
        }

        void reserve(size_t n)
        {
            // 如果新容量大于旧容量,则开辟空间
            if (n > _capacity)
            {
                char* tmp = new char[n + 1];
                strcpy(tmp, _str);

                // 释放原来旧空间,然后使用新空间
                delete[] _str;
                _str = tmp;
                _capacity = n;
            }
        }




        /////////////////////////////////////////////////////////////

        // access

        char& operator[](size_t pos)
        {
            assert(pos < _size);

            return _str[pos];
        }

        const char& operator[](size_t pos)const
        {
            assert(pos < _size);

            return _str[pos];
        }



        /////////////////////////////////////////////////////////////

        //relational operators

        bool operator<(const string& s)
        {
            int ret = strcmp(_str, s._str);
            return ret < 0;
        }

        bool operator<=(const string& s)
        {
            int ret = strcmp(_str, s._str);
            return ret < 0 || ret == 0;
        }

        bool operator>(const string& s)
        {
            int ret = strcmp(_str, s._str);
            return ret > 0;

        }

        bool operator>=(const string& s)
        {
            int ret = strcmp(_str, s._str);
            return ret > 0 || ret == 0;
        }

        bool operator==(const string& s)
        {
            int ret = strcmp(_str,s._str);
            return ret == 0;
        }

        bool operator!=(const string& s)
        {
            int ret = strcmp(_str, s._str);
            return ret != 0;
        }



        // 返回c在string中第一次出现的位置

        size_t find(char c, size_t pos = 0) const
        {
            assert(pos < _size);
            for (size_t i = pos; i < _size; i++)
            {
                if (_str[i] == c)
                    return i;
            }
            return std::string::npos;
        }

        // 返回子串s在string中第一次出现的位置

        size_t find(const char* s, size_t pos = 0) const
        {
            assert(pos < _size);
            const char* p = strstr(_str + pos, s);
            if (p)
            {
                return p - _str;
            }
            else
            {
                return std::string::npos;
            }
        }

        //生成子字符串
        //返回一个新构造的对象,其值初始化为此对象的子字符串的副本
        string substr(size_t pos = 0, size_t len = std::string::npos)const
        {
            string sub;
            //if (len == npos || len >= _size-pos)
            if (len >= _size - pos)
            {
                for (size_t i = pos; i < _size; i++)
                {
                    sub += _str[i];
                }
            }
            else
            {
                for (size_t i = pos; i < pos + len; i++)
                {
                    sub += _str[i];
                }
            }
            return sub;
        }

        // 在pos位置前插入字符c/字符串str,并返回该字符的位置

        string& insert(size_t pos, char c)
        {
            assert(pos <= _size);

            if (_size == _capacity)
            {
                reserve(_capacity == 0 ? 4 : _capacity * 2);
            }
            
            //int end = _size;
            //while (end >=(int)pos)
            //{
            //    _str[end + 1] = _str[end];
            //    --end;
            //}
            //_str[pos] = c;
            //++_size;

            size_t end = _size + 1;
            while (end > pos)
            {
                _str[end] = _str[end - 1];
                end--;
            }
            _str[pos] = c;
            ++_size;

            return *this;
        }

        string& insert(size_t pos, const char* str)
        {
            assert(pos <= _size);
            size_t len = strlen(str);
            if (_size + len > _capacity)
            {
                reserve(_size + len);
            }
            
            size_t end = _size + len;
            //while(end>=pos+len)
            //while(end-(int)len>=(int)pos)
            while (end > pos+len-1)
            {
                _str[end] = _str[end - len];
                --end;
            }
            strncpy(_str + pos, str, len);
            _size+=len;

            return *this;
        }


        // 删除pos位置上的元素,并返回该元素的下一个位置

        string& erase(size_t pos, size_t len)
        {
            assert(pos < _size);
            if (len == std::string::npos || len >= _size - pos)//len+pos>=_size
            {
                _str[pos] = '\0';
                _size = pos;
            }
            else
            {
                strcpy(_str + pos, _str + pos + len);
                _size -= len;
            }
            return *this;
        }

    private:

        char* _str;

        size_t _capacity;

        size_t _size;

    };

    ostream& operator<<(ostream& out, const string& s)
    {
        for (auto ch : s)
        {
            out << ch;
        }
        return out;
    }


    ////低效率版本(如果输入数据太多的话,会造成频繁扩容,效率低)
    //istream& operator>>(istream& in, string& s)
    //{
    //    s.clear();
    //    char ch;
    //    //in>>ch;// cin 和 printf 取不到空格和换行这样的分隔符,所以用get()
    //    ch = in.get();
    //    while (ch != ' ' && ch != '\n')
    //    {
    //        s += ch;
    //        ch = in.get();
    //    }
    //    return in;
    //}

    //高效率版本  (一把开空间)
    istream& operator>>(istream& in, string& s)
    {
        s.clear();
        char ch;
        ch = in.get();
        char buff[128];
        size_t i = 0;
        while (ch != ' ' && ch != '\n')
        {
            buff[i++] = ch;
            if (i == 127)
            {
                buff[127] = '\0';
                s += buff;
                i = 0;
            }
            ch = in.get();
        }
        if (i > 0)
        {
            buff[i] = '\0';
            s += buff;
        }
        return in;
    }

    istream& getline(istream& in, string& s)
    {
        s.clear();
        char ch;
        ch = in.get();
        char buff[128];
        size_t i = 0;
        while (ch != '\n')
        {
            buff[i++] = ch;
            if (i == 127)
            {
                buff[127] = '\0';
                s += buff;
                i = 0;
            }
            ch = in.get();
        }
        if (i > 0)
        {
            buff[i] = '\0';
            s += buff;
        }
        return in;
    }

    void swap(string& x, string& y)
    {
        x.swap(y);
    }
    
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值