您的位置:首页 > 其它

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;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: