fork download
  1. #include <iostream>
  2. #include <memory>
  3. #include <vector>
  4. #include <string>
  5. #include <algorithm>
  6. #include <iterator>
  7.  
  8. static int default_constructed = 0;
  9. static int constructed = 0;
  10. static int copied = 0;
  11. static int moved = 0;
  12. static int destroyed = 0;
  13.  
  14. struct Foo
  15. {
  16. std::string attr1;
  17. std::vector<int> attr2;
  18.  
  19. Foo() : attr1(), attr2() { ++default_constructed; }
  20.  
  21. Foo(const std::string &str,
  22. const std::vector<int> &v) :
  23. attr1(str), attr2(v) { ++constructed; }
  24.  
  25. Foo(Foo &&x) :
  26. attr1( std::move(x.attr1) ),
  27. attr2( std::move(x.attr2) ) { ++moved; }
  28.  
  29. Foo(const Foo &x) : Foo(x.attr1, x.attr2) { ++copied; }
  30.  
  31. ~Foo() { ++destroyed; }
  32. };
  33.  
  34. int main()
  35. {
  36. std::allocator<Foo> alloc;
  37.  
  38. // выделим место под 100 объектов Foo
  39. Foo *array100 = alloc.allocate(100);
  40.  
  41. // запишем кол-во
  42. size_t size = 100;
  43.  
  44. // и сконструируем столько же
  45. std::uninitialized_fill( array100,
  46. array100 + size,
  47. Foo("string", {1000, 42}) ); // constructed = 1 (ref)
  48. // copy constructed = 100
  49. // destroyed = 1
  50.  
  51. // увеличим место - 1000
  52. Foo *array1000 = alloc.allocate(1000);
  53. size_t new_size = 1000;
  54.  
  55. // объекты array100 нужно переместить в новое место
  56. // если тип обладает перемещающим конструктором, то будет использован именно он
  57. std::uninitialized_copy( std::make_move_iterator(array100),
  58. std::make_move_iterator(array100 + size),
  59. array1000 ); // move constructed = 100
  60.  
  61. // инициализируем остальные 900 элементов
  62. std::uninitialized_fill( array1000 + size,
  63. array1000 + new_size,
  64. Foo("string v2", {1000, 87}) ); // constructed = 1 (ref)
  65. // copy constructed = 900
  66. // destroyed = 1
  67.  
  68. // объекты array100 больше не валидны
  69. std::for_each(array100, array100 + size, [&alloc](Foo &x) { x.~Foo(); } );
  70. // destroyed = 100
  71.  
  72. // освободим место под array100
  73. alloc.deallocate(array100, size);
  74. array100 = nullptr;
  75.  
  76. // обновим размер
  77. size = new_size;
  78.  
  79. // array1000 больше не нужен
  80. // уничтожим объекты
  81. std::for_each(array1000, array1000 + size, [&alloc](Foo &x) { x.~Foo(); } );
  82. //destroyed = 1000
  83.  
  84. // освободим память
  85. alloc.deallocate(array1000, size);
  86.  
  87. // перестраховка
  88. array1000 = nullptr;
  89.  
  90. std::cout << "Objects default constructed = " << default_constructed
  91. << "\nObjects constructed = " << constructed
  92. << "\nObjects copy constructed = " << copied
  93. << "\nObjects move constructed = " << moved
  94. << "\nObjects destroyed = " << destroyed;
  95.  
  96. return 0;
  97. }
  98.  
Success #stdin #stdout 0s 2988KB
stdin
Standard input is empty
stdout
Objects default constructed = 0
Objects constructed = 1002
Objects copy constructed = 1000
Objects move constructed = 100
Objects destroyed = 1102