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