欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++模擬實(shí)現(xiàn)string類(lèi)的實(shí)例代碼

 更新時(shí)間:2023年08月13日 14:21:11   作者:派小星233  
這篇文章主要給大家介紹了C++如何模擬實(shí)現(xiàn)string類(lèi),文章通過(guò)代碼示例講解的非常詳細(xì),有完整的實(shí)現(xiàn)過(guò)程,具有一定的參考價(jià)值,需要的朋友可以參考下

成員變量

public:
        //類(lèi)外可能要訪問(wèn),設(shè)計(jì)成公有
        static const size_t npos;
 private:
        //指向?qū)嶋H存儲(chǔ)字符串的空間
        char* _str;
        //記錄容量
        size_t _capacity;
        //記錄有效字符,'\0'不算
        size_t _size;
//記得類(lèi)外定義靜態(tài)變量
const size_t string::npos = -1;

在這里插入圖片描述

構(gòu)造和析構(gòu)

string(const char* str = "")
    :_capacity(strlen(str))
    ,_size(_capacity)
{
    _str = new char[_capacity + 1];
    strcpy(_str, str);
}
string(const string& s)
    :_capacity(s._capacity)
    ,_size(s._size)
{
    _str = new char[_capacity + 1];
    strcpy(_str, s._str);
}
~string()
{
    delete[] _str;
    _str = nullptr;
    _size = _capacity = 0;
}

容量相關(guān)

1.獲取容器大小(_size)和容量(_capacity)

//加const修飾this指針,因?yàn)閏onst修飾對(duì)象也需要調(diào)用這幾個(gè)接口
size_t size()const
{
    return _size;
}
size_t capacity()const
{
    return _capacity;
}
bool empty()const
{  
    //為空返回true,為假返回false
    return (_size == 0);
}

2.擴(kuò)容(reserve)

void reserve(size_t n)
{
    //只有n大于容量才進(jìn)行擴(kuò)容
    if (n > _capacity)
    {
        //重新開(kāi)一片空間,拷貝完成后釋放原空間
        //修改指針指向,更改容量
        char* tmp = new char[n + 1];
        strcpy(tmp, _str);
        delete[] _str;
        _str = tmp;
        _capacity = n;
    }
}

3.更改容器大小

//設(shè)計(jì)成半缺省
void resize(size_t n, char c = '\0')
{
    //n > _size,擴(kuò)容后用c填滿容器
    if (n > _size)
    {
        reserve(n);
        for (size_t i = _size; i < _capacity; i++)
        {
            _str[i] = c;
        }
        _str[_capacity] = '\0';
        _size = _capacity;
    }
    else
    {
        //n <= _size的情況,直接把下標(biāo)n的位置改為'\0',修改_size即可
        _str[n] = '\0';
        _size = n;
    }
}

在這里插入圖片描述

修改相關(guān)

1.尾插

//尾部插入一個(gè)字符
void push_back(char c)
{
    //先判斷是否擴(kuò)容
    if (_size == _capacity)
        reserve(_capacity == 0 ? 4 : _capacity * 2);
    //把原'\0'位置修改為新字符,記得補(bǔ)'\0'
    _str[_size] = c;
    _str[_size + 1] = '\0';
    _size++;
}
//+=復(fù)用即可
string& operator+=(char c)
{
    push_back(c);
    return (*this);
}
//尾部插入字符串
void append(const char* str)
{
   size_t len = strlen(str);
   //先判斷是否擴(kuò)容
    if (len + _size > _capacity)
        reserve(len + _size);
    //從原'\0'位置開(kāi)始拷貝
    strcpy(_str + _size, str);
    //更新_size
    _size += len;
}
string& operator+=(const char* str)
{
    //+=復(fù)用即可
    append(str);
    return (*this);
}

在這里插入圖片描述

2.指定位置插入

// 在pos位置上插入字符c
string& insert(size_t pos, char c)
 {
     //斷言,不然可能越界
     assert(pos <= _size);
     if (_size == _capacity)
         reserve(2 * _capacity);
     //pos位置后字符后移一位
     for (int i = _size; i >= (int)pos; i--)        
         _str[i + 1] = _str[i];
     _str[pos] = c;
     _size++;
     return (*this);
 }
 //在pos位置上插入字符串str
 string& insert(size_t pos, const char* str)
 {
     //斷言,不然可能越界
     assert(pos <= _size);
     size_t len = strlen(str);
     if ((_size + len) > _capacity)
         reserve(_size + len);
     for (int i = _size; i >= (int)pos; i--)
     {
         _str[i + len] = _str[i];
     }
     for (int i = 0; i < len; i++)
     {
         _str[pos++] = str[i];
     }
     _size += len;
     return (*this);
 }

在這里插入圖片描述

3.指定位置刪除

// 刪除pos位置上的元素
string& erase(size_t pos, size_t len = npos)
{
    assert(pos <= _size);
    //要?jiǎng)h除的字符數(shù)大于后面字符,就把pos位置和后面全部刪除完
    if (len == npos || pos + len >= _size)
    {
        _size = pos;
        _str[_size] = '\0';
    }
    else
    {
        for (size_t i = pos; i <= pos + _size - len; i++)
        {
            _str[i] = _str[i + len];
        }
        _size -= len;
    }
    return (*this);
}

在這里插入圖片描述

4.清空

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

5.交換兩個(gè)對(duì)象

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

比較相關(guān)

//寫(xiě)好< 和 == ,其它復(fù)用即可
bool operator<(const string& s)const
{       
    return strcmp(_str, s._str) < 0;
}
bool operator<=(const string& s)const
{
    return (*this) < s || (*this) == s;
}
bool operator>(const string& s)const
{
    return !((*this) <= s);
}
bool operator>=(const string& s)const
{
    return !((*this) < s);
}
bool operator==(const string& s)const
{
    return strcmp(_str, s._str) == 0;
}
bool operator!=(const string& s)const
{
    return !((*this == s));
}

訪問(wèn)相關(guān)

char& operator[](size_t index)
{
     assert(index <= _size);
     return _str[index];
}
//函數(shù)重載,這個(gè)版本專(zhuān)門(mén)給const用
 const char& operator[](size_t index)const
{
    assert(index <= _size);
    return _str[index];
}

迭代器相關(guān)

//string的迭代器底層是指針
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);
}

查找相關(guān)

// 查找字符,返回c在string中第一次出現(xiàn)的位置
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 npos;
}
//查找子串,返回子串s在string中第一次出現(xiàn)的位置
size_t find(const char* s, size_t pos = 0) const
{
    //斷言,不然可能越界
    assert(pos < _size);
    //直接調(diào)用庫(kù)函數(shù)找到子串位置
    const char* p = strstr(_str + pos, s);
    if (p)
        return p - _str;//指針相減得到指針間元素?cái)?shù)量,剛好為下標(biāo)
    else
        return npos;
}

其它成員函數(shù)

1.截取子串

string substr(size_t pos, size_t len = npos)
{
    assert(pos < _size);
    string s;
    size_t end = pos + len;
    //如果len大于后面所剩的字符,就把后面全部截取
    if (len == npos || end >= _size)
    {
        len = _size - pos;
        end = _size;
    }
    s.reserve(len);
    for (size_t i = pos; i < end; i++)
    {
        s += _str[i];
    }
    return s;
}

2.取得C格式字符串

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

3.賦值

//這里使用傳值傳參,編譯器自行完成拷貝,交換兩者即可
string& operator=(string s)
{
     swap(s);
     return (*this);
 }

非成員函數(shù)

ostream& operator<<(ostream& _cout, const string& s)
{
    _cout << s.c_str() << endl;
    return _cout;
}
istream& operator>>(istream& _cin, string& s)
{
    s.clear();
    //避免多次擴(kuò)容,以128為一組進(jìn)行寫(xiě)入
    char tmp[128] = "";
    int i = 0;
    char ch = '0';
    ch = _cin.get();
    while (ch != ' ' && ch != '\n')
    {
        tmp[i++] = ch;
        if (i == 127)
        {
            tmp[i] = '\0';
            s += tmp;
            i = 0;
        }
        ch = _cin.get();
    }
    if (i != 0)
    {
        tmp[i] = '\0';
        s += tmp;
    }
    return _cin;
}

完整代碼

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string.h>
#include<assert.h>
using namespace std;
namespace MyStd
{
    class string
    {
    public:
        typedef char* iterator;
        typedef const char* const_iterator;
        string(const char* str = "")
            :_capacity(strlen(str))
            ,_size(_capacity)
        {
            _str = new char[_capacity + 1];
            strcpy(_str, str);
        }
        string(const string& s)
            :_capacity(s._capacity)
            ,_size(s._size)
        {
            _str = new char[_capacity + 1];
            strcpy(_str, s._str);
        }
        string& operator=(string s)
        {
            swap(s);
            return (*this);
        }
        ~string()
        {
            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
        //尾部插入一個(gè)字符
        void push_back(char c)
        {
            //先判斷是否擴(kuò)容
            if (_size == _capacity)
                reserve(_capacity == 0 ? 4 : _capacity * 2);
            //把原'\0'位置修改為新字符,記得補(bǔ)'\0'
            _str[_size] = c;
            _str[_size + 1] = '\0';
            _size++;
        }
        //+=復(fù)用即可
        string& operator+=(char c)
        {
            push_back(c);
            return (*this);
        }
        //尾部插入字符串
        void append(const char* str)
        {
           size_t len = strlen(str);
           //先判斷是否擴(kuò)容
            if (len + _size > _capacity)
                reserve(len + _size);
            //從原'\0'位置開(kāi)始拷貝
            strcpy(_str + _size, str);
            //更新_size
            _size += len;
        }
        string& operator+=(const char* str)
        {
            //+=復(fù)用即可
            append(str);
            return (*this);
        }
        void clear()
        {
            _str[0] = '\0';
            _size = 0;
        }
        void swap(string& s)
        {
            std::swap(_str, s._str);
            std::swap(_capacity, s._capacity);
            std::swap(_size, s._size);
        }
        const char* c_str()const
        {
            return _str;
        }
        /
        // capacity
        //加const修飾this指針,因?yàn)閏onst修飾對(duì)象也需要調(diào)用這幾個(gè)接口
        size_t size()const
        {
            return _size;
        }
        size_t capacity()const
        {
            return _capacity;
        }
        bool empty()const
        {
            //為空返回true,為假返回false
            return (_size == 0);
        }
        //設(shè)計(jì)成半缺省
        void resize(size_t n, char c = '\0')
        {
            //n > _size,擴(kuò)容后用c填滿容器
            if (n > _size)
            {
                reserve(n);
                for (size_t i = _size; i < _capacity; i++)
                {
                    _str[i] = c;
                }
                _str[_capacity] = '\0';
                _size = _capacity;
            }
            else
            {
                //n <= _size的情況,直接把下標(biāo)n的位置改為'\0',修改_size即可
                _str[n] = '\0';
                _size = n;
            }
        }
        void reserve(size_t n)
        {
            //只有n大于容量才進(jìn)行擴(kuò)容
            if (n > _capacity)
            {
                //重新開(kāi)一片空間,拷貝完成后釋放原空間
                //修改指針指向,更改容量
                char* tmp = new char[n + 1];
                strcpy(tmp, _str);
                delete[] _str;
                _str = tmp;
                _capacity = n;
            }
        }
        /
        // access
        char& operator[](size_t index)
        {
            assert(index <= _size);
            return _str[index];
        }
        const char& operator[](size_t index)const
        {
            assert(index <= _size);
            return _str[index];
        }
        /
        //relational operators
        //寫(xiě)好< 和 == ,其它復(fù)用即可
        bool operator<(const string& s)const
        {       
            return strcmp(_str, s._str) < 0;
        }
        bool operator<=(const string& s)const
        {
            return (*this) < s || (*this) == s;
        }
        bool operator>(const string& s)const
        {
            return !((*this) <= s);
        }
        bool operator>=(const string& s)const
        {
            return !((*this) < s);
        }
        bool operator==(const string& s)const
        {
            return strcmp(_str, s._str) == 0;
        }
        bool operator!=(const string& s)const
        {
            return !((*this == s));
        }
        // 查找字符,返回c在string中第一次出現(xiàn)的位置
        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 npos;
        }
        //查找子串,返回子串s在string中第一次出現(xiàn)的位置
        size_t find(const char* s, size_t pos = 0) const
        {
            //斷言,不然可能越界
            assert(pos < _size);
            //直接調(diào)用庫(kù)函數(shù)找到子串位置
            const char* p = strstr(_str + pos, s);
            if (p)
                return p - _str;//指針相減得到指針間元素?cái)?shù)量,剛好為下標(biāo)
            else
                return npos;
        }
        string substr(size_t pos, size_t len = npos)
        {
            assert(pos < _size);
            string s;
            size_t end = pos + len;
            //如果len大于后面所剩的字符,就把后面全部截取
            if (len == npos || end >= _size)
            {
                len = _size - pos;
                end = _size;
            }
            s.reserve(len);
            for (size_t i = pos; i < end; i++)
            {
                s += _str[i];
            }
            return s;
        }
        // 在pos位置上插入字符c
        string& insert(size_t pos, char c)
        {
            //斷言,不然可能越界
            assert(pos <= _size);
            if (_size == _capacity)
                reserve(2 * _capacity);
            //pos位置后字符后移一位
            for (int i = _size; i >= (int)pos; i--)        
                _str[i + 1] = _str[i];
            _str[pos] = c;
            _size++;
            return (*this);
        }
        //在pos位置上插入字符串str
        string& insert(size_t pos, const char* str)
        {
            //斷言,不然可能越界
            assert(pos <= _size);
            size_t len = strlen(str);
            if ((_size + len) > _capacity)
                reserve(_size + len);
            for (int i = _size; i >= (int)pos; i--)
            {
                _str[i + len] = _str[i];
            }
            for (int i = 0; i < len; i++)
            {
                _str[pos++] = str[i];
            }
            _size += len;
            return (*this);
        }
        // 刪除pos位置上的元素
        string& erase(size_t pos, size_t len = npos)
        {
            assert(pos <= _size);
            //要?jiǎng)h除的字符數(shù)大于后面字符,就把pos位置和后面全部刪除完
            if (len == npos || pos + len >= _size)
            {
                _size = pos;
                _str[_size] = '\0';
            }
            else
            {
                for (size_t i = pos; i <= pos + _size - len; i++)
                {
                    _str[i] = _str[i + len];
                }
                _size -= len;
            }
            return (*this);
        }
    public:
        //類(lèi)外可能要訪問(wèn),設(shè)計(jì)成公用
        static const size_t npos;
    private:
        //指向?qū)嶋H存儲(chǔ)字符串的空間
        char* _str;
        //記錄容量
        size_t _capacity;
        //記錄有效字符,'\0'不算
        size_t _size;
    };
    ostream& operator<<(ostream& _cout, const string& s)
    {
        _cout << s.c_str() << endl;
        return _cout;
    }
    istream& operator>>(istream& _cin, string& s)
    {
        s.clear();
        //避免多次擴(kuò)容
        char tmp[128] = "";
        int i = 0;
        char ch = '0';
        ch = _cin.get();
        while (ch != ' ' && ch != '\n')
        {
            tmp[i++] = ch;
            if (i == 127)
            {
                tmp[i] = '\0';
                s += tmp;
                i = 0;
            }
            ch = _cin.get();
        }
        if (i != 0)
        {
            tmp[i] = '\0';
            s += tmp;
        }
        return _cin;
    }
    //靜態(tài)成員在外部定義
    const size_t string::npos = -1; 
};

以上就是C++模擬實(shí)現(xiàn)string類(lèi)的實(shí)例代碼的詳細(xì)內(nèi)容,更多關(guān)于C++模擬實(shí)現(xiàn)string類(lèi)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之順序數(shù)組的實(shí)現(xiàn)

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之順序數(shù)組的實(shí)現(xiàn)

    這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之順序數(shù)組的實(shí)現(xiàn)的相關(guān)資料,這里提供實(shí)現(xiàn)實(shí)例,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下
    2017-08-08
  • C語(yǔ)言排序算法之桶排序解析

    C語(yǔ)言排序算法之桶排序解析

    這篇文章主要介紹了C語(yǔ)言排序算法之桶排序解析,桶排序Bucket?sort或所謂的箱排序,是一個(gè)排序算法,工作的原理是將數(shù)組分到有限數(shù)量的桶里,每個(gè)桶再分別排序,大部分是在分桶時(shí),即插入時(shí)就排序了,需要的朋友可以參考下
    2023-10-10
  • 如何用C語(yǔ)言生成簡(jiǎn)單格式的xml

    如何用C語(yǔ)言生成簡(jiǎn)單格式的xml

    本篇文章是對(duì)使用C語(yǔ)言生成簡(jiǎn)單格式的xml的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++ 內(nèi)存分區(qū)模型的使用(代碼區(qū)、全局區(qū)、棧區(qū)、堆區(qū)、new)

    C++ 內(nèi)存分區(qū)模型的使用(代碼區(qū)、全局區(qū)、棧區(qū)、堆區(qū)、new)

    這篇文章主要介紹了C++ 內(nèi)存分區(qū)模型的使用(代碼區(qū)、全局區(qū)、棧區(qū)、堆區(qū)、new),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • C++ MD5的源碼實(shí)例詳解

    C++ MD5的源碼實(shí)例詳解

    這篇文章主要介紹了C++ MD5的源碼實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • C++基類(lèi)指針和派生類(lèi)指針之間的轉(zhuǎn)換方法講解

    C++基類(lèi)指針和派生類(lèi)指針之間的轉(zhuǎn)換方法講解

    今天小編就為大家分享一篇關(guān)于C++基類(lèi)指針和派生類(lèi)指針之間的轉(zhuǎn)換方法講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • C語(yǔ)言中不定參數(shù)?...?的語(yǔ)法以及函數(shù)封裝

    C語(yǔ)言中不定參數(shù)?...?的語(yǔ)法以及函數(shù)封裝

    不定參數(shù)是指函數(shù)可以接收不確定個(gè)數(shù)的參數(shù),下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中不定參數(shù)?...?的語(yǔ)法以及函數(shù)封裝的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • 詳細(xì)分析C++ 異常處理

    詳細(xì)分析C++ 異常處理

    這篇文章主要介紹了C++ 異常處理的的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • C語(yǔ)言用數(shù)組實(shí)現(xiàn)反彈球消磚塊

    C語(yǔ)言用數(shù)組實(shí)現(xiàn)反彈球消磚塊

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言用數(shù)組實(shí)現(xiàn)反彈球消磚塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 最新評(píng)論