您的位置:首页 > 其它

自己动手写STL中的vector

2013-11-13 16:20 197 查看
M0313-array_class_template.h
#ifndef DYNAMIC_ARRAY_H_
#define DYNAMIC_ARRAY_H_

#include <cstddef>
#include <stdio.h>

struct A {
A(int n = 0): i(n) {
printf("A(%d)\n", i);
}

~A() {
printf("~A(%d)\n", i);
}

int i;
};

// typedef int T;
//typedef A T;

template<typename T>
class DynamicArray {
public:
enum { DEFAULT_CAP = 16 };

explicit DynamicArray(size_t capactiy = DEFAULT_CAP);
DynamicArray(size_t count, T val);

DynamicArray(const DynamicArray& rhs);
DynamicArray& operator=(const DynamicArray& rhs);

~DynamicArray();

void push_back(T val);
void insert(size_t pos, T val);

void pop_back();
void erase(size_t pos);

T operator[](size_t index) const;
T& operator[](size_t index);

const T* data() const;
T* data();

size_t size() const;
size_t capacity() const;
bool empty() const;

private:
void destroy();

private:
T* ar;
size_t _capacity;
size_t _size;
};

#include "M0313-array_class_template.ipp"

#endif

#include <iostream>
#include <cstring>

template<typename T>
DynamicArray<T>::DynamicArray(size_t cap): _capacity(cap), _size() {
ar = static_cast<T*>(::operator new(sizeof(T) * _capacity));
}

template<typename X>
DynamicArray<X>::DynamicArray(size_t count, X val): _capacity(count), _size(count) {
ar = static_cast<X*>(::operator new(sizeof(X) * _capacity));

for (size_t i = 0; i < _size; ++i)
new (ar + i) X(val);
}

template<typename T>
DynamicArray<T>::DynamicArray(const DynamicArray<T>& rhs): _capacity(rhs._capacity), _size(rhs._size) {
ar = static_cast<T*>(::operator new(sizeof(T) * _capacity));
for (size_t i = 0; i < _size; ++i)
new (ar + i) T(*(rhs.ar + i));
}

template<typename T>
DynamicArray<T>& DynamicArray<T>::operator=(const DynamicArray<T>& rhs) {
if (this != &rhs) {
_capacity = rhs._capacity;
_size = rhs._size;

destroy();
for (size_t i = 0; i < _size; ++i)
new (ar + i) T(*(rhs.ar + i));
}

return *this;
}

template<typename T>
DynamicArray<T>::~DynamicArray() {

destroy();
}

template<typename T>
void DynamicArray<T>::push_back(T val) {
if (_size == _capacity) {
_capacity *= 2;

T* tmp = static_cast<T*>(::operator new(sizeof(T) * _capacity));
for (size_t i = 0; i < _size; ++i)
new (tmp + i) T(*(ar + i));

destroy();
ar = tmp;
}

new (ar + _size) T(val);
++_size;

}
// TODO
template<typename T>
void DynamicArray<T>::insert(size_t pos, T val) {
if (_size == _capacity) {
_capacity *= 2;
T* tmp = static_cast<T*>(::operator new(sizeof(T) * _capacity));
for (size_t i = 0; i < pos; ++i)
new (tmp + i) T(*(ar + i));

for (size_t i = pos + 1; i < _size; ++i)
new (tmp + i) T(*(ar + (i - 1)));

new (tmp + pos) T(val);

destroy();
ar = tmp;
} else {
for (size_t i = _size; i > pos; --i)
ar[i] = ar[i - 1];

new (ar + pos) T(val);
}

++_size;
}

template<typename T>
void DynamicArray<T>::pop_back() {
(ar + (_size - 1))->~T();
--_size;
}

template<typename T>
void DynamicArray<T>::erase(size_t pos) {
(ar + pos)->~T();

for (size_t i = pos; i < _size - 1; ++i)
ar[i] = ar[i + 1];

--_size;
}

template<typename T>
T DynamicArray<T>::operator[](size_t index) const {
return ar[index];
}

template<typename T>
T& DynamicArray<T>::operator[](size_t index) {
return ar[index];
}

template<typename T>
size_t DynamicArray<T>::size() const {
return _size;
}

template<typename T>
size_t DynamicArray<T>::capacity() const {
return _capacity;
}

template<typename T>
bool DynamicArray<T>::empty() const {
return (_size == 0);
}

template<typename T>
const T* DynamicArray<T>::data() const {
return ar;
}

template<typename T>
T* DynamicArray<T>::data() {
return ar;
}

template<typename T>
void DynamicArray<T>::destroy() {
for (size_t i = 0; i < _size; ++i)
ar[i].~T();
::operator delete(ar);
}

测试程序

#include "M0313-array_class_template.h"

#include <iostream>
#include <cstring>

std::ostream& operator<<(std::ostream& os, const A& a1) {
return os << a1.i;
}

template<typename T>
void print(const DynamicArray<T>& a) {
const size_t N = a.size();
for (size_t i = 0; i < N; ++i)
std::cout << a[i] << ' ';
std::cout << '\n';
}

int main() {
using namespace std;

DynamicArray<A> a1(6);
a1.push_back(A(120));
a1.push_back(A(190));
a1.push_back(A(123));
a1.push_back(A(129));
a1.push_back(A(620));
a1.push_back(A(890));

// print(a1);
cout << "1------------------------------\n";

a1.insert(3, A(1000));
print(a1);
cout << "a1.size(): " << a1.size() << endl;
cout << "2------------------------------\n";

a1.erase(3);
a1.pop_back();

cout << "a1.size(): " << a1.size() << endl;
print(a1);
cout << "3------------------------------\n";

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