I'm performing some tests about move semantics, and my class behavior seems weird for me.
Given the mock class VecOfInt:
class VecOfInt { public: VecOfInt(size_t num) : m_size(num), m_data(new int[m_size]) {} ~VecOfInt() { delete[] m_data; } VecOfInt(VecOfInt const& other) : m_size(other.m_size), m_data(new int[m_size]) { std::cout << "copy..." <<std::endl; std::copy(other.m_data, other.m_data + m_size, m_data); } VecOfInt(VecOfInt&& other) : m_size(other.m_size) { std::cout << "move..." << std::endl; m_data = other.m_data; other.m_data = nullptr; } VecOfInt& operator=(VecOfInt const& other) { std::cout << "copy assignment..." << std::endl; m_size = other.m_size; delete m_data; m_data = nullptr; m_data = new int[m_size]; m_data = other.m_data; return *this; } VecOfInt& operator=(VecOfInt&& other) { std::cout << "move assignment..." << std::endl; m_size = other.m_size; m_data = other.m_data; other.m_data = nullptr; return *this; } private: size_t m_size; int* m_data; }; OK CASE
When I insert a single value in-place:
int main() { std::vector<VecOfInt> v; v.push_back(10); return 0; }Then it gives me the following output (what I think is fine):
move...WEIRD CASE
When I insert three different values in-place:
int main() { std::vector<VecOfInt> v; v.push_back(10); v.push_back(20); v.push_back(30); return 0; }Then the output calls the copy constructor 3 times:
move... move... copy... move... copy... copy...
What I'm missing here?
operator=(VecOfInt const&)should check for self-assignment before making a copy, and it is notdelete'ingm_datacorrectly. Andoperator=(VecOfInt&&)is leaking memory since the original array pointed to bym_datais lost. You can combine the twooperator=into a single implementation by passingotherby value and letting its constructors decide between copy and move operations. And also look into the copy-swap idiom to avoid leaks.operator=is changing the state of*thisbefore new memory is allocated, thus if an exception is thrown, your object is corrupted.VecOfIntto usestd::vector<int>internally, then all these issues go away.v.reserve(3);as the vector grows it has to copy the objects to the resized vector.