STL-lesson001_1_模板实现Array类
2017-12-19 00:01
239 查看
/*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; }
相关文章推荐
- 数据离散化模板(用STL实现)
- 六、STL的数值计算---数组(向量)运算---gslice类和gslice_array类模板
- 没有模板代码膨胀的STL:一、设计目标与实现思路
- 类模板模拟实现STL中Vector
- stl实现全排列模板
- LIS 模板 (最长上升/下降子序列) STL实现
- Codeforces 427C - Checkposts 极大连通分量Tarjan算法模板题(STL实现)
- STL 队列模板实现
- hash表 拉链法 仿sgi stl 非模板简单实现
- 类模板模拟实现STL中List
- 自己实现STL模板upper_bound() 和lower_bound()
- C++ 模板应用举例_模板实现STL类(堆栈)
- POJ 2833 求平均数。 模板:STL实现大根堆和小根堆
- 进阶篇_STL详解(函数模板特化,类模板特化,用模板实现自己的通用算法)
- C模板实现STL容器中的vector
- 使用模板和STL实现对象池
- 模板实现简易queue
- C++模板编程实现二维数组
- Windows 8 Directx 开发学习笔记(十三)利用模板实现木箱镜像
- ASP.NET 2.0中实现模板中的数据绑定