我們之前有<C++模板編程模塊>中的第<四>節 理解空間配置器allocator優化STL中的Vector 我將在此基礎上加入迭代器功能代碼 Iterator 為什麼可以遍歷所有的容器的方式都一樣? auto it =continer.beign(); for( ;it!=continer.end( ...
我們之前有<C++模板編程模塊>中的第<四>節 理解空間配置器allocator優化STL中的Vector
我將在此基礎上加入迭代器功能代碼
Iterator 為什麼可以遍歷所有的容器的方式都一樣?
auto it =continer.beign();
for( ;it!=continer.end();++it){
cout<<*it<<endl;
}
//我們在自己的容器里的 Iterator de ++ , * 由自己來實現,所有對外部使用者來看都是統一的.
//泛型演算法能夠給所有的容器都使用,也是基於容器對外提供了統一的遍歷介面, 其參數接受的都是容器的迭代器
#include <iostream>
using namespace std;
class person {
public:
//構造函數
person(int _age=1,char * _pname=nullptr):
age(_age)
{
if (_pname == nullptr) {
pname = new char[1];
pname[0] = '\0';
}
else {
int size = strlen(_pname);
pname = new char[size + 1];
strcpy(pname, _pname);
}
cout << "創建student對象,地址=" << this << endl;
}
//拷貝構造函數
person(const person & _person) {
this->age = _person.age;
int size = strlen(_person.pname);
pname = new char[size + 1];
strcpy(this->pname, _person.pname);
}
//賦值函數
person & operator=(const person & _person) {
if (this == &_person) { return *this; }
delete[]pname;
pname = nullptr;
this->age = _person.age;
int size = strlen(_person.pname);
pname = new char[size + 1];
strcpy(this->pname, _person.pname);
return *this;
}
~person() {
cout << "析構 person =" <<pname << " "<<age << endl;
delete[]pname;
pname = nullptr;
}
private:
int age;
char * pname;
friend ostream & operator<<(ostream & out, const person & _value);
};
ostream & operator<<(ostream & out, const person & _value) {
cout << _value.pname<<" == "<< _value.age << " " << endl;
return out;
}
template <typename T>
class Allocate4 {
public:
//分配記憶體空間,不創建對象
T * allocator(int size=4) {
return (T *)malloc(sizeof(T)*size);
}
//在指定的記憶體空間地址,構建 T對象
void constract(T * pAddress, const T & _val) {
new (pAddress) T(_val);
}
//釋放指定位置的記憶體空間
void delAllocator(T * pAddress) {
if (pAddress != nullptr) {
free(pAddress);
pAddress = nullptr;
}
}
//析構指定記憶體位置
void destory(T * pAddress) {
pAddress->~T();//調用析構函數
}
};
template<typename T,typename Allocate= Allocate4<T>>
//類模板
class MyVector4 {
public:
MyVector4<T,Allocate>(int size = 4 , const Allocate _rallocator = Allocate4<T>)
: _allocator(_rallocator)
{
pfirst = _allocator.allocator(size);
last = pfirst;
pend = pfirst + size;
cout << "MyVector開闢記憶體地址=" << pfirst<<endl;
}
MyVector4<T, Allocate>(const MyVector4<T, Allocate> & _vector)
{
//1:根據原vector的空間大小申請新的記憶體空間
pfirst = _allocator.allocator(_vector.size());
last = pfirst;
pend = pfirst + size;
//2:將原vector空間中的有效對象賦值到新的vector中
T * _pFlag = _vector.pfirst;
while (_pFlag != _vector.last) {
_allocator.constract(last, *_pFlag);
_pFlag++;
last++;
}
}
MyVector4<T, Allocate> & operator=(const MyVector4<T, Allocate> & _vector)
{
if (this == &_vector) {
return *this;
}
//1:析構現有vector中的有效對象
T * _pFlag = pfirst;
while (_pFlag !=last) {
_allocator.destory(_pFlag);
_pFlag++;
}
//2:釋放現有的vector申請的堆記憶體空間
_allocator.delAllocator(pfirst);
pfirst = nullptr;
pend = nullptr;
last = nullptr;
//3:根據_vector的記憶體空間大小,申請新的堆記憶體空間
pfirst = _allocator.allocator(_vector.size());
last = pfirst;
pend = pfirst + _vector.size();
//4:將_vector中有效的對象複製到現在新的堆空間中
T * _pFlag = _vector.pfirst;
while (_pFlag != _vector.last) {
_allocator.constract(last, *_pFlag);
_pFlag++;
last++;
}
}
void pushBack(const T & _val) {
if (Full()) {
Expend();
}
_allocator.constract(last, _val);
cout << "pushBack 原對象 地址=" << &_val <<"放在記憶體位置 "<<last<< endl;
this->last++;
}
void popBack() {
if (Empty()) { return ; }
_allocator.destory(this->last-1);
this->last--;
}
//記憶體空間擴展
void Expend() {
int newSize = 2*this->size();
//1:申請新的記憶體空間
T * tep_pfirst = _allocator.allocator(newSize);
T * tep_last = tep_pfirst;
T * tep_pend = tep_pfirst + newSize;
//2:原當前vector中原有效的對象複製到新的堆空間上
T * _pFlag = pfirst;
while (_pFlag != last) {
_allocator.constract(tep_last, *_pFlag);
_pFlag++;
tep_last++;
}
//3:析構原有對象
_pFlag = pfirst;
while (_pFlag != last) {
_allocator.destory(_pFlag);
_pFlag++;
}
//4:釋放原有的vector申請的堆記憶體空間
_allocator.delAllocator(pfirst);
pfirst = nullptr;
pend = nullptr;
last = nullptr;
//5:指針重新指向
pfirst = tep_pfirst;
last = tep_last;
pend = tep_pend;
cout << "MyVector空間2倍擴展,新的地址=" << pfirst << endl;
}
bool Empty() const {
return this->pfirst == this->last;
}
bool Full() const {
return this->pend == this->last;
}
int size() {
return this->pend - this->pfirst;
}
void showVectorInfo() {
T * tep = pfirst;
while (tep < last)
{
cout << "列印Vector中有效對象地址=" << tep << endl;
tep++;
}
}
//定義屬於自己的迭代器
class Iterator {
public:
Iterator( T * _pAddress=nullptr):pAddress(_pAddress) {
}
const T & operator*() const {
return *pAddress;
}
T & operator*() {
return *pAddress;
}
//前置++
void operator++() {
this->pAddress++;
}
bool operator!=(const Iterator & src) const {
return this->pAddress != src.pAddress;
}
private:
T * pAddress;
};
Iterator begin() const {
return Iterator(this->pfirst);
}
Iterator end() const {
return Iterator(this->last);
}
private:
T * pfirst;//指向首元素地址
T * pend; // 指向容器最後位置的下一個地址
T * last; //指向最後一個有效元素的下一個位置
Allocate _allocator;
};
void testV4() {
MyVector4<person, Allocate4<person>> v5(4,Allocate4<person>());
person p1(10,"zs1");
v5.pushBack(p1);
person p2(20, "zs2");
v5.pushBack(p2);
person p3(30, "zs3");
v5.pushBack(p3);
person p4(40, "zs4");
v5.pushBack(p4);
v5.showVectorInfo();
cout << "-------" << endl;
person p5(50, "zs5");
v5.pushBack(p5);
v5.showVectorInfo();
v5.popBack();
MyVector4<person, Allocate4<person>>::Iterator it_begin = v5.begin();
MyVector4<person, Allocate4<person>>::Iterator it_end = v5.end();
cout << "---iterator begin----" << endl;
for (; it_begin != it_end; ++it_begin) {
cout << *it_begin << endl;
}
cout << "---iterator end----" << endl;
}
int main() {
testV4();
system("pause");
return 0;
}//pendl