fork download
  1. #include <cstdlib>
  2. #include <cassert>
  3. #include <iostream>
  4. #include <utility> // for std::swap, std::move
  5.  
  6. class Vector {
  7. int* _p_array;
  8. int _capacity, _size;
  9. public:
  10. Vector() { std::cout << "Call constructor" << std::endl; init(2); }
  11. Vector(size_t cap) { std::cout << "Call constructor 2" << std::endl; init(cap); }
  12. Vector(const Vector & rhs) {
  13. std::cout << "Call copy constuctor" << std::endl;
  14. init(rhs.capacity());
  15. for (int i = 0; i < rhs.size(); ++i) _p_array[i] = rhs[i];
  16. _size = rhs._size;
  17. }
  18. Vector(Vector && rhs) : Vector() { // IMPORTANT!: call default constructor to ensure that after swap, it is safe to desstruct
  19. std::cout << "Call move constuctor" << std::endl;
  20. swap(*this, rhs);
  21. }
  22. ~Vector() {
  23. std::cout << "Call destuctor" << std::endl;
  24. delete [] _p_array; _p_array = nullptr; _capacity = _size = 0;
  25. }
  26. Vector& operator = (Vector rhs) {
  27. std::cout << "Assignment operator" << std::endl;
  28. swap(*this, rhs);
  29. return *this;
  30. }
  31. friend void swap(Vector & x, Vector & y) {
  32. using std::swap;
  33. swap(x._p_array, y._p_array);
  34. swap(x._capacity, y._capacity);
  35. swap(x._size, y._size);
  36. }
  37. void init(size_t cap) {
  38. _p_array = new int [cap]; _capacity = cap; _size = 0;
  39. if (_p_array == nullptr) {
  40. printf("Out of memory"); assert(0);
  41. exit(1);
  42. }
  43. }
  44. int size() const { return _size; }
  45. int capacity() const { return _capacity; }
  46. void resize(size_t new_cap) {
  47. assert(size() <= new_cap);
  48. int* p_new_array = new int[new_cap]; _capacity = new_cap;
  49. for (int i = 0; i < size(); ++i)
  50. p_new_array[i] = _p_array[i];
  51. delete [] _p_array; _p_array = nullptr;
  52. _p_array = p_new_array;
  53. }
  54. void push_back(int x) {
  55. if (size() == capacity())
  56. resize(2*capacity());
  57. _p_array[_size++] = x;
  58. }
  59. int& operator [] (int pos) { return _p_array[pos]; }
  60. int operator [] (int pos) const { return _p_array[pos]; }
  61. friend std::ostream & operator << (std::ostream & os, const Vector & v) {
  62. for (int i = 0; i < v.size(); ++i)
  63. os << ((i != 0) ? " " : "") << v[i];
  64. return os;
  65. }
  66. };
  67.  
  68. Vector read_vector() {
  69. Vector v;
  70. int x;
  71. while (scanf("%d", &x) == 1)
  72. v.push_back(x);
  73. return v;
  74. }
  75.  
  76.  
  77. int main() {
  78. std::cout << "Return value optimization" << std::endl;
  79. // C++ Return value optimization
  80. // https://w...content-available-to-author-only...d.com/en/Return_value_optimization
  81. Vector v = read_vector();
  82. std::cout << " v contains : " << v << std::endl;
  83.  
  84. std::cout << "Copy vector" << std::endl;
  85. Vector v2(v);
  86. std::cout << " v2 contains : " << v2 << std::endl;
  87.  
  88. Vector v3(std::move(v2));
  89. std::cout << " v2 contains : " << v2 << std::endl;
  90. std::cout << " v3 contains : " << v3 << std::endl;
  91.  
  92. Vector v4 = v3;
  93. std::cout << " v3 contains : " << v3 << std::endl;
  94. std::cout << " v4 contains : " << v4 << std::endl;
  95.  
  96. Vector v5;
  97. v5 = v3;
  98. std::cout << " v3 contains : " << v3 << std::endl;
  99. std::cout << " v5 contains : " << v5 << std::endl;
  100.  
  101. return 0;
  102. }
  103.  
Success #stdin #stdout 0s 3468KB
stdin
1 2 3 4 5
stdout
Return value optimization
Call constructor
  v contains : 1 2 3 4 5
Copy vector
Call copy constuctor
  v2 contains : 1 2 3 4 5
Call constructor
Call move constuctor
  v2 contains : 
  v3 contains : 1 2 3 4 5
Call copy constuctor
  v3 contains : 1 2 3 4 5
  v4 contains : 1 2 3 4 5
Call constructor
Call copy constuctor
Assignment operator
Call destuctor
  v3 contains : 1 2 3 4 5
  v5 contains : 1 2 3 4 5
Call destuctor
Call destuctor
Call destuctor
Call destuctor
Call destuctor