STL-lesson001_1_模板实现Array类

/*MyString.h*/

#ifndef _MYSTRING_H_
#define _MYSTRING_H_
#define _CRT_SECURE_NO_WARNINGS
#include <cstring>
#include <limits>
#include <string>


namespace PoEdu
{
    class CMyString
    {
    public:
        // constructor
        CMyString();
        CMyString(const CMyString &other);
        CMyString(const CMyString &other, size_t pos, size_t len = nopos_);
        CMyString(const char *str);
        CMyString(const char *str, size_t len);
        CMyString(size_t len, char c);
        CMyString(const char *first, const char *last);

        // operator=
        CMyString& operator= (const CMyString &other);
        CMyString& operator= (const char* str);
        CMyString& operator= (char c);

        // deconstructor
        ~CMyString();

        // similar to iterator
        char *Begin() const;
        char *End() const;
        char *Rbegin() const;
        char *REnd() const;

        // capcity
        size_t Size() const;
        size_t Length() const;
        size_t Max_size() const;
        void Resize(size_t len);
        void Resize(size_t len, char c);
        size_t Capacity() const;
        void Reserve(size_t len);
        void Clear();
        bool Empty() const;

        // Element access:
        char& operator[] (size_t index);
        const char& operator[] (size_t index) const;
        char& At(size_t index);
        const char& At(size_t index) const;

        // Modifiers:
        CMyString& operator+= (const CMyString &otehr);
        CMyString& operator+= (const char *str);
        CMyString& operator+= (char c);
        CMyString& Append(const CMyString& other);
        CMyString& Append(const CMyString& other, size_t subpos, size_t sublen);
        CMyString& Append(const char* str);
        CMyString& Append(const char* str, size_t len);
        CMyString& Append(size_t len, char c);
        void Push_back(char c);
        CMyString& Assign(const CMyString& other);
        CMyString& Assign(const CMyString& other, size_t subpos, size_t sublen);
        CMyString& Assign(const char* str);
        CMyString& Assign(const char* str, size_t len);
        CMyString& Assign(size_t len, char c);
        CMyString& Insert(size_t pos, const CMyString& other);
        CMyString& Insert(size_t pos, const CMyString& other, size_t subpos, size_t sublen);
        CMyString& Insert(size_t pos, const char* str);
        CMyString& Insert(size_t pos, const char* str, size_t len);
        CMyString& Insert(size_t pos, size_t len, char c);
        CMyString& Erase(size_t pos = 0, size_t len = nopos_);

        void Swap(CMyString& other);

        // Non-member function overloads
        friend CMyString operator+(const CMyString &lhs, const CMyString &rhs);
        friend CMyString operator+(const CMyString &lhs, const char *rhs);
        friend CMyString operator+(const char *lhs, const CMyString& rhs);
        friend CMyString operator+(const CMyString &lhs, char rhs);
        friend CMyString operator+(char lhs, const CMyString &rhs);
        friend std::ostream &operator<<(std::ostream &os, const CMyString &other);

        // String operations :
        const char* C_str() const;

    private:
        char *Alloc(const char *str);

    public:
        static const size_t nopos_ = -1;

    private:
        char *str_;
        size_t length_;         // 当前长度
        size_t capacity_;       // 当前容量,可以每次增加16个     stl中的逻辑是每次分配16个字节空间,只不过最后一个字节是用来保存\0的
        const size_t max_size_; // 最大长度
    };
}

#endif // !_MYSTRING_H_

/*MyString.cpp*/

#include "MyString.h"
#include <iostream>


namespace PoEdu
{
    CMyString::CMyString() : max_size_(UINT_MAX-1)
    {
        str_ = Alloc("");
    }

    CMyString::CMyString(const char *str) : max_size_(UINT_MAX-1)
    {
        str_ = Alloc(str);
    }

    CMyString::CMyString(const CMyString& other) : max_size_(UINT_MAX-1)
    {
        str_ = Alloc(other.str_);
    }

    CMyString::CMyString(const CMyString& other, size_t pos, size_t len) : max_size_(UINT_MAX-1)
    {
        if (len > other.length_)
            length_ = other.length_ - pos;
        else
            length_ = len - pos;
        str_ = new char[length_ + sizeof(char)];
        memset(str_, 0, length_ + sizeof(char));

        for (size_t index=0; index < length_; ++index)
        {
            str_[index] = other.str_[index + pos];
        }
    }

    CMyString::CMyString(const char* str, size_t len) : max_size_(UINT_MAX-1)
    {
        size_t curlen = strlen(str);
        length_ = len;
        str_ = new char[length_ + sizeof(char)];
        memset(str_, 0, length_ + sizeof(char));

        for (size_t index = 0; index < length_ && index < curlen; ++index)
        {
            str_[index] = str[index];
        }

        if (length_ > len)
            str_[len] = '\0';
        else
            str_[length_] = '\0';
    }

    CMyString::CMyString(size_t len, char c) : max_size_(UINT_MAX-1)
    {
        length_ = len;
        str_ = new char[length_ + sizeof(char)];
        memset(str_, 0, length_ + sizeof(char));
        for (size_t index = 0; index < length_; ++index)
        {
            str_[index] = c;
        }
    }

    CMyString::CMyString(const char* first, const char* last) : max_size_(UINT_MAX-1)
    {
        length_ = last - first;
        str_ = new char[length_ + sizeof(char)];
        memset(str_, 0, length_ + sizeof(char));
        memcpy(str_, first, length_);
    }

    CMyString& CMyString::operator=(const CMyString& other)
    {
        if (this != &other)
        {
            delete[] str_;
            str_ = Alloc(other.str_);
        }

        return *this;
    }

    CMyString& CMyString::operator=(const char* str)
    {
        delete[] str_;
        str_ = Alloc(str);
        return *this;
    }

    CMyString& CMyString::operator=(char c)
    {
        delete[] str_;
        length_ = 1;
        str_ = new char[length_ + 1];
        memset(str_, 0, length_ + sizeof(char));
        str_[0] = c;
        return *this;
    }

    CMyString::~CMyString()
    {
        delete[] str_;
    }

    char* CMyString::Begin() const
    {
        return str_;
    }

    char* CMyString::End() const
    {
        return &(str_[length_ + 1]);    // 返回的是一个未维护的地址
    }

    char* CMyString::Rbegin() const
    {
        return End();
    }

    char* CMyString::REnd() const
    {
        return Begin();
    }

    size_t CMyString::Size() const
    {
        return length_;
    }

    size_t CMyString::Length() const
    {
        return length_;
    }

    size_t CMyString::Capacity() const
    {
        return capacity_;
    }

    void CMyString::Reserve(size_t len)
    {
        if (len > capacity_)
        {
            while (capacity_ < len)
            {
                capacity_ += 16;
            }

            char *temp = new char[capacity_ + sizeof(char)];
            memset(temp, 0, capacity_ + sizeof(char));
            strcpy(temp, str_);
            delete str_;
            str_ = temp;
        }
    }

    // 用非const版本调用const版本
    // 问题!!!下面的两种实现有什么区别呢?貌似在使用上是一样的
    char& CMyString::operator[](size_t index)
    {
        return const_cast<char &>(const_cast<const CMyString &>(*this)[index]);
    }

    const char& CMyString::operator[](size_t index) const
    {
        return str_[index];
    }

    char & CMyString::At(size_t index)
    {
        return const_cast<char &>(static_cast<const CMyString &>(*this).At(index));
    }

    const char & CMyString::At(size_t index) const
    {
        int temp = index;
        if (index >= length_)
        {
            std::cout << "超出范围" << std::endl;
            temp = length_ - 1;
        }

        return str_[temp];
    }

    CMyString & CMyString::operator+=(const CMyString & other)
    {
        return operator+=(other.str_);
    }

    CMyString & CMyString::operator+=(const char * str)
    {
        length_ += strlen(str);

        while (capacity_ < length_)
        {
            capacity_ += 16;
        }

        char *temp = new char[capacity_ + sizeof(char)];
        memset(temp, 0, capacity_ + sizeof(char));
        strcpy(temp, str_);
        strcat(temp, str);
        delete[] str_;
        str_ = temp;

        return *this;
    }

    CMyString & CMyString::operator+=(char c)
    {
        char temp[2] = { 0 };
        temp[0] = c;
        return operator+=(temp);
    }

    CMyString & CMyString::Append(const CMyString & other)
    {
        *this += other;
        return *this;
    }

    CMyString & CMyString::Append(const CMyString &other, size_t subpos, size_t sublen)
    {
        for (size_t index = subpos; index<subpos+sublen; ++index)
        {
            *this += other[index];
        }

        return *this;
    }

    CMyString & CMyString::Append(const char *str)
    {
        *this += str;
        return *this;
    }

    CMyString & CMyString::Append(const char *str, size_t len)
    {
        for (size_t index=0; index<len; ++index)
        {
            *this += str[index];
        }

        return *this;
    }

    CMyString & CMyString::Append(size_t len, char c)
    {
        for (size_t index=0; index<len; ++index)
        {
            *this += c;
        }

        return *this;
    }

    void CMyString::Push_back(char c)
    {
        *this += c;
    }

    CMyString & CMyString::Assign(const CMyString & other)
    {
        (*this).Clear();
        *this += other;
        return *this;
    }

    CMyString & CMyString::Assign(const CMyString & other, size_t subpos, size_t sublen)
    {
        (*this).Clear();
        (*this).Append(other, subpos, sublen);
        return *this;
    }

    CMyString & CMyString::Assign(const char * str)
    {
        (*this).Clear();
        *this += str;
        return *this;
    }

    CMyString & CMyString::Assign(const char * str, size_t len)
    {
        (*this).Clear();
        (*this).Append(str, len);
        return *this;
    }

    CMyString & CMyString::Assign(size_t len, char c)
    {
        (*this).Clear();
        (*this).Append(len, c);
        return *this;
    }

    CMyString & CMyString::Insert(size_t pos, const CMyString & other)
    {
        length_ += other.length_;

        while (capacity_ < length_)
        {
            capacity_ += 16;
        }

        char *temp = new char[capacity_ + sizeof(char)];
        memset(temp, 0, capacity_ + sizeof(char));
        memcpy(temp, str_, pos);
        strcat(temp, other.C_str());
        strcat(temp, &(str_[pos]));
        delete[] str_;
        str_ = temp;

        return *this;
    }

    CMyString & CMyString::Insert(size_t pos, const CMyString & other, size_t subpos, size_t sublen)
    {
        length_ += sublen;

        while (capacity_ < length_)
        {
            capacity_ += 16;
        }

        char *temp = new char[capacity_ + sizeof(char)];
        memset(temp, 0, capacity_ + sizeof(char));
        memcpy(temp, str_, pos);
        memcpy(&temp[pos], &other[subpos], sublen);
        strcat(temp, &str_[pos]);
        delete[] str_;
        str_ = temp;

        return *this;
    }

    CMyString & CMyString::Insert(size_t pos, const char * str)
    {
        CMyString temp(str);
        (*this).Insert(pos, temp);
        return *this;
    }

    CMyString & CMyString::Insert(size_t pos, const char * str, size_t len)
    {
        CMyString temp(str, len);
        (*this).Insert(pos, temp);
        return *this;
    }

    CMyString & CMyString::Insert(size_t pos, size_t len, char c)
    {
        CMyString temp(len, c);
        (*this).Insert(pos, temp);
        return *this;
    }

    CMyString & CMyString::Erase(size_t pos, size_t len)
    {
        char *temp = new char[capacity_ + sizeof(char)];
        memset(temp, 0, capacity_ + sizeof(char));

        if (len < length_-pos)
        {
            memcpy(temp, str_, pos);
            strcat(temp, &str_[pos + len]);
        }
        else
        {
            memcpy(temp, str_, pos);
        }
        delete[] str_;
        str_ = temp;

        return *this;
    }

    void CMyString::Swap(CMyString & other)
    {
        CMyString temp(other);
        other = *this;
        *this = temp;
    }

    size_t CMyString::Max_size() const
    {
        return max_size_;
    }

    void CMyString::Resize(size_t len)
    {
        bool bCopyAll = false;

        if (length_ < len)
            bCopyAll = true;
        length_ = len;
        char *temp = new char[length_ + sizeof(char)];
        memset(temp, 0, length_ + sizeof(char));
        if (bCopyAll)
        {
            strcpy(temp, str_);
        }
        else
        {
            for (size_t index = 0; index < length_; ++index)
            {
                temp[index] = str_[index];
            }
        }
        delete[] str_;
        str_ = temp;
    }

    void CMyString::Resize(size_t len, char c)
    {
        size_t length = length_;
        Resize(len);
        for (; length < length_; ++length)
        {
            str_[length] = c;
        }
    }

    void CMyString::Clear()
    {
        length_ = 0;
        delete[] str_;
        str_ = new char[sizeof(char)];
        str_[0] = '\0';
    }

    bool CMyString::Empty() const
    {
        return !length_;
    }

    const char * CMyString::C_str() const
    {
        return str_;
    }

    char* CMyString::Alloc(const char* str)
    {
        capacity_ = 15;
        length_ = strlen(str);
        while (capacity_ < length_)
        {
            capacity_ += 16;
        }
        char *temp = new char[capacity_ + sizeof(char)];
        memset(temp, 0, capacity_ + sizeof(char));
        strcpy(temp, str);

        return temp;
    }

    std::ostream& operator<<(std::ostream& os, const CMyString& other)
    {
        for (size_t index = 0; index < other.length_; ++index)
        {
            std::cout << other.str_[index];
        }

        return os;
    }

    // 在写二元运算符的时候,都使用友元函数来实现,因为这样共明确,并没有隐藏第一个对象
    CMyString operator+(const CMyString &lhs, const CMyString &rhs)
    {
        return (CMyString(lhs) += rhs);
    }
    CMyString operator+(const CMyString &lhs, const char *rhs)
    {
        return (CMyString(lhs) += rhs);
    }
    CMyString operator+(const char *lhs, const CMyString &rhs)
    {
        return (CMyString(lhs) += rhs);
    }
    CMyString operator+(const CMyString &lhs, char rhs)
    {
        return (CMyString(lhs) += rhs);
    }
    CMyString operator+(char lhs, const CMyString &rhs)
    {
        CMyString temp;
        temp = lhs;
        temp += rhs;
        return temp;
    }
}

MyArray类

/*MyArray.h*/

#ifndef _MYARRAY_H_
#define _MYARRAY_H_
#include <cstddef>
#include <limits>
#include <iostream>

namespace PoEdu
{
    template<typename T>
    class CMyArray
    {
    public:
        // Member functions
        CMyArray();
        CMyArray(const CMyArray &other);
        CMyArray(size_t n, const T &val);
        CMyArray(const T *first, const T *last);
        CMyArray &operator=(const CMyArray &other);
        ~CMyArray();

        // Iterators:
        T *Begin() const;
        T *End() const;
        T *Rbegin() const;
        T *Rend() const;

        // Capacity:
        size_t Size() const;
        size_t Max_size() const;
        void Resize(size_t len, T str);
        size_t Capacity() const;
        bool Empty() const;
        void Reserve(size_t len);

        // Element access:
        T &operator[](size_t index);
        const T &operator[](size_t index) const;
        T &At(size_t index);
        const T &At(size_t index) const;
        T &Front();
        const T &Front() const;
        T &Back();
        const T &Back() const;

        // Modifiers:
        void Assign(size_t len, const T& other);
        void Push_back(const T &val);
        void Pop_back();
        void Insert(size_t pos, size_t len, const T &other);
        T *Erase(size_t pos);
        T *Erase(size_t first, size_t last);
        void Swap(CMyArray &other);
        void Clear();

    private:
        T *data_;
        size_t size_;
        // 加上默认分配一定空间大小的变量
        size_t capacity_;
        const size_t max_size_;
    };



    template<typename T>
    CMyArray<T>::CMyArray() : max_size_(UINT_MAX / 4)
    {
        size_ = 0;
        capacity_ = 5;
        data_ = new T[capacity_];
    }
    template<typename T>
    inline CMyArray<T>::CMyArray(const CMyArray & other)
    {
        if (&other != this)
        {
            size_ = other.size_;
            capacity_ = other.capacity_;
            data_ = new T[capacity_];
            for (size_t i = 0; i < size_; ++i)
            {
                data_[i] = other.data_[i];
            }
        }
    }
    template<typename T>
    CMyArray<T>::CMyArray(size_t n, const T & val) : max_size_(UINT_MAX / 4)
    {
        size_ = n;
        capacity_ = 5;
        while (capacity_ < size_)
        {
            capacity_ *= 2;
        }
        data_ = new T[size_];
        for (size_t i = 0; i < size_; ++i)
        {
            data_[i] = val; // 等号一定是提升出来的
        }
    }
    template<typename T>
    CMyArray<T>::CMyArray(const T * first, const T * last) : max_size_(UINT_MAX / 4)
    {
        size_ = (last - first) / sizeof(T);
        data_ = new T[capacity_];
        T *pAddr = const_cast<T *>(first);

        for (size_t i = 0; i < size_; ++i)
        {
            data_[i] = *pAddr;
            pAddr += sizeof(T);
        }
    }
    template<typename T>
    CMyArray<T> & CMyArray<T>::operator=(const CMyArray & other)
    {
        if (&other != this)
        {
            delete[] data_;
            size_ = other.size_;
            capacity_ = other.capacity_;
            data_ = new T[capacity_];
            for (size_t i = 0; i < size_; ++i)
            {
                data_[i] = other.data_[i];
            }
        }

        return *this;
    }
    template<typename T>
    CMyArray<T>::~CMyArray()
    {
        delete[] data_;
    }
    template<typename T>
    T * CMyArray<T>::Begin() const
    {
        return data_;
    }
    template<typename T>
    T * CMyArray<T>::End() const
    {
        return &(data_[size_]);
    }
    template<typename T>
    T * CMyArray<T>::Rbegin() const
    {
        return End();
    }
    template<typename T>
    T * CMyArray<T>::Rend() const
    {
        return Begin();
    }
    template<typename T>
    size_t CMyArray<T>::Size() const
    {
        return size_;
    }
    template<typename T>
    size_t CMyArray<T>::Max_size() const
    {
        return size_;
    }
    template<typename T>
    void CMyArray<T>::Resize(size_t len, T str)
    {
        if (len < size_)
        {
            // 销毁后面的几个元素
            for (size_t index = size_ - 1; index >= len; --index)
            {
                Pop_back();
            }
        }
        else
        {
            // 以str来填充后面的元素
            for (size_t index = size_; index < len; ++index)
            {
                Push_back(str);
            }
        }
    }
    template<typename T>
    size_t CMyArray<T>::Capacity() const
    {
        return capacity_;
    }
    template<typename T>
    bool CMyArray<T>::Empty() const
    {
        return !size_;
    }
    template<typename T>
    void CMyArray<T>::Reserve(size_t len)
    {
        if (len > size_)
        {
            for (size_t index = size_; index < len; ++index)
            {
                Push_back("");
            }
        }
    }
    template<typename T>
    T& CMyArray<T>::operator[](size_t index)
    {
        return const_cast<T&>(static_cast<const CMyArray &>(*this)[index]);
    }
    template<typename T>
    const T & CMyArray<T>::operator[](size_t index) const
    {
        return data_[index];
    }
    template<typename T>
    T & CMyArray<T>::At(size_t index)
    {
        return const_cast<T &>(static_cast<const CMyArray &>(*this).At(index));
    }
    template<typename T>
    const T & CMyArray<T>::At(size_t index) const
    {
        size_t temp = index;
        if (index >= size_)
        {
            std::cout << "超出范围" << std::endl;
            temp = size_ - 1;
        }

        return data_[temp];
    }
    template<typename T>
    T & CMyArray<T>::Front()
    {
        return const_cast<T &>(static_cast<const CMyArray &>(*this).Front());
    }
    template<typename T>
    const T & CMyArray<T>::Front() const
    {
        return At(0);
    }
    template<typename T>
    T & CMyArray<T>::Back()
    {
        return const_cast<T &>(static_cast<const CMyArray &>(*this).Back());
    }
    template<typename T>
    const T & CMyArray<T>::Back() const
    {
        return At(size_ - 1);
    }
    template<typename T>
    void CMyArray<T>::Assign(size_t len, const T & other)
    {
        delete[] data_;
        memset(data_, 0, capacity_ * sizeof(T));
        if (len < size_)
        {
            for (size_t index = 0; index < len; ++index)
            {
                data_[index] = other;
            }
        }
        else
        {
            size_ = len;
            while (capacity_ < size_)
            {
                capacity_ *= 2;
            }
            data_ = new T[capacity_];
            for (size_t index = 0; index < size_; ++index)
            {
                data_[index] = other;
            }
        }
    }
    template<typename T>
    void CMyArray<T>::Push_back(const T & val)
    {
        while (capacity_ < size_)
        {
            capacity_ += 5;
        }
        T *temp = new T[size_ + 1];
        for (size_t i = 0; i < size_; ++i)
        {
            temp[i] = data_[i];
        }
        temp[size_] = val;
        size_ += 1;
        delete[] data_;
        data_ = temp;
    }
    template<typename T>
    void CMyArray<T>::Pop_back()
    {
        T *temp = new T[capacity_];
        memset(temp, 0, capacity_ * sizeof(T));
        --size_;
        for (size_t index = 0; index < size_; ++index)
        {
            temp[index] = data_[index];
        }
        delete[] data_;
        data_ = temp;
    }
    template<typename T>
    void CMyArray<T>::Insert(size_t pos, size_t len, const T & other)
    {
        T *temp = new T[size_ + len];
        for (size_t index = 0; index < pos; ++index)
        {
            temp[index] = data_[index];
        }
        for (size_t index = pos; index < pos + len; ++index)
        {
            temp[index] = other;
        }
        for (size_t index = pos + len; index < size_ + len; ++index)
        {
            temp[index] = data_[index - len];
        }
        size_ += len;
        delete[] data_;
        data_ = temp;
    }
    template<typename T>
    T * CMyArray<T>::Erase(size_t pos)
    {
        T *temp = new T[capacity_];
        memset(temp, 0, capacity_ * sizeof(T));
        for (size_t index = 0; index < pos; ++index)
        {
            temp[index] = data_[index];
        }
        for (size_t index = pos; index < size_ - 1; ++index)
        {
            temp[index] = data_[index + 1];
        }
        --size_;
        delete[] data_;
        data_ = temp;

        return &(data_[pos]);
    }
    template<typename T>
    T * CMyArray<T>::Erase(size_t first, size_t last)
    {
        T *temp = new T[capacity_];
        memset(temp, 0, capacity_ * sizeof(T));
        for (size_t index = 0; index < first; ++index)
        {
            temp[index] = data_[index];
        }
        for (size_t index = first; index < size_ - (last - first); ++index)
        {
            temp[index] = data_[index + last - first];
        }

        size_ -= (last - first);
        delete[] data_;
        data_ = temp;

        return &(data_[first]);
    }
    template<typename T>
    void CMyArray<T>::Swap(CMyArray & other)
    {
        CMyArray temp(other);
        other = *this;
        *this = temp;
    }
    template<typename T>
    void CMyArray<T>::Clear()
    {
        delete[] data_;
    }
}

#endif // !_MYARRAY_H_

/*MyArray.cpp*/


#include "MyArray.h"
#include "MyString.h"

namespace PoEdu
{

}

Test

#include <iostream>
#include <string>
#include <vector>

#include "MyString.h"
#include "MyArray.h"

int main()
{
    PoEdu::CMyArray<PoEdu::CMyString> demo;
    demo.Push_back("11111111");
    demo.Push_back("22222222");
    demo.Push_back("33333333");
    demo.Push_back("44444444");
    demo.Push_back("55555555");
    demo.Push_back("66666666");
    demo.Push_back("77777777");
    demo.Push_back("88888888");

    for (unsigned int i = 0; i < demo.Size(); ++i)
    {
        std::cout << demo.At(i) << std::endl;
    }
    std::cout << std::endl;

    // 删除下标为3的元素
    demo.Erase(3);

    for (unsigned int i = 0; i < demo.Size(); ++i)
    {
        std::cout << demo.At(i) << std::endl;
    }
    std::cout << std::endl;

    system("pause");
    return 0;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值