STL-lesson001_1_模板实现Array类

来源:互联网 发布:wowapp是什么软件 编辑:程序博客网 时间:2024/06/05 08:14
/*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;}

这里写图片描述

原创粉丝点击