fork download
  1. #include <iostream>
  2. #include <memory>
  3. #include <cassert>
  4.  
  5. struct Hoge {
  6. int i;
  7. public:
  8. Hoge(int j) : i(j) {}
  9. void print() const {
  10. std::cout << i << std::endl;
  11. }
  12. };
  13.  
  14. template <class T, class Allocator = std::allocator<T> >
  15. class MyVector {
  16. int Elements;
  17. int Num;
  18. T* hp;
  19. Allocator alloc;
  20. public:
  21. MyVector() : Elements(0), hp(0) {}
  22. void push_back(const T& h) {
  23. T* newmem = alloc.allocate(Elements + 1); // 要素を一つ増やすと再割当てが起きる可能性がある
  24. std::uninitialized_copy(hp, hp + Elements, newmem); // 古い要素を新しいメモリーにコピーする
  25. alloc.construct(newmem + Elements, h); // 追加された要素のコンストラクタ
  26. // 再割当てが起きたと見なして古い要素を破棄・メモリを解放する
  27. for (int i = 0; i < Elements; i++)
  28. alloc.destroy(&hp[i]);
  29. alloc.deallocate(hp, Elements);
  30. Elements++;
  31. Num++;
  32. hp = newmem;
  33. }
  34. T pop_back() {
  35. // std::assert(Elements != 0);
  36. T tmp = hp[--Elements];
  37. alloc.destroy(&hp[Elements]); // 要素を破棄(破棄してもメモリは解放されない事に注意、これがC++11でstd::shrink_to_fit()が用意された理由でもある)
  38. return tmp;
  39. }
  40. int size() const {
  41. return Elements;
  42. }
  43. T& operator[](int i) {
  44. // std::assert(Elements != 0);
  45. return hp[i];
  46. }
  47. ~MyVector() {
  48. for (int i = 0; i < Elements; i++)
  49. alloc.destroy(&hp[i]);
  50. alloc.deallocate(hp, Num);
  51. }
  52. };
  53.  
  54. int main()
  55. {
  56. MyVector<Hoge> mh;
  57. mh.push_back(Hoge(1));
  58. mh.push_back(Hoge(2));
  59. std::cout << "size = " << mh.size() << std::endl;
  60. mh[0].print();
  61. mh[1].print();
  62. mh.pop_back();
  63. std::cout << "size = " << mh.size() << std::endl;
  64. }
Success #stdin #stdout 0.02s 2812KB
stdin
Standard input is empty
stdout
size = 2
1
2
size = 1