While trying to implement MyVector I end up with:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
class MyVector
{
int m_size = 0;
int m_capacity = 0;
T* m_data = nullptr;
public:
MyVector()
{
cout << "defautl ctor" << endl;
realloc(2);
}
MyVector(const MyVector& v)
: m_size(v.m_size),
m_capacity(v.m_capacity)
{
cout << "copy ctor" << endl;
m_data = new T[m_size];
*m_data = *v.m_data;
}
MyVector(MyVector&& v)
: m_size(v.m_size),
m_capacity(v.m_capacity)
{
cout << "move ctor" << endl;
m_data = move(v.m_data);
v.m_data = nullptr;
v.m_size = 0;
v.m_capacity = 0;
}
MyVector& operator= (const MyVector& v)
{
cout << "copy assignment operator" << endl;
// m_size = v.m_size;
// m_capacity = v.m_capacity;
// *m_data = *v.m_data;
MyVector<int> copy = v;
swap(*this, copy);
return *this;
}
void push_back(const T& value)
{
if (!(m_size < m_capacity))
{
// cout << value << " size is " << m_size << " capacity is " << m_capacity << endl;
realloc(m_size*2);
// return;
}
m_data[m_size++] = value;
}
T& operator[] (int index)
{
cout << "index " << index << " of size " << m_size << endl;
if (!(index < m_size))
cout << "index out of bounds" << endl;
return m_data[index];
}
int size()
{
return m_size;
}
T* begin()
{
return &m_data[0];
}
T* end()
{
return &m_data[size()];
}
private:
void realloc(int new_capacity)
{
// cout << __func__ << " new capacity " << new_capacity << endl;
T* data = new T[new_capacity];
for (int i = 0; i < m_size; i++)
data[i] = m_data[i];
delete[] m_data;
m_data = data;
m_capacity = new_capacity;
}
};
int main(int argc, char** argv)
{
cout << "starting..." << endl;
MyVector<int> a;
a.push_back(7);
MyVector<int> d;
d = a;
cout << a[0] << endl;
cout << d[0] << endl;
return 0;
}
Where the operator= is
MyVector& operator= (const MyVector& v)
{
cout << "copy assignment operator" << endl;
// m_size = v.m_size;
// m_capacity = v.m_capacity;
// *m_data = *v.m_data;
MyVector<int> copy = v; // copy and swap
swap(*this, copy);
return *this;
}
However this led to what seems to be a recursive behavior. So, is my understanding of the copy and swap approach wrong? Or is there something else I'm missing?
As stated in comments, you did not implement a
swap()function forMyVector, so the statementswap(*this, copy);is callingstd::swap()(one of the many pitfalls of usingusing namespace std;), which will invoke youroperator=again, hence the recursive behavior you are seeing.Also, your copy constructor is not implemented correctly. It is not copying all of the elements from the input array into the new array. It is copying only the 1st element.
Also, you are missing a destructor to free the allocated array.
Also, since
MyVectorhas both copy and move constructors, your two assignmentoperator='s can (and should) be merged into one operator that takes aMyVectorby value. This lets the compiler decide whether to call the operator with copy or move semantics depending on whether the caller is passing in an lvalue or an rvalue, respectively. The operator can then justswapwhatever it is given, as the input will have already been copied or moved before the operator is entered.Try something more like this: