I recently revisited the copy constructor, assignment operator, copy swap idom seen here: What is the copy-and-swap idiom? and many other places -
The Above link is an excellent post - but I still had a few more questions - These questions are answered in a bunch of places, on stackoverflow and many other sites, but I have not seen a lot of consistency -
1 - Should you have try
-catch
around the areas where we allocate the new memory for a deep copy in the copy constructor ? (Ive seen it both ways)
2 - With regards to inheritance for both the copy constructor and assignment operator, when should the base class functions be called, and when should these functions be virtual?
3 - Is std::copy
the best way for duplicating memory in the copy constructor? I have seen it with memcpy
, and seen others say memcpy
the worst thing on earth.
Consider the example Below (Thanks for all the feedback), it prompted some additional questions:
4 - Should we be checking for self assignment? If so where
5 - Off topic question, but I have seen swapped used as :
std::copy(Other.Data,Other.Data + size,Data);
should it be:
std::copy(Other.Data,Other.Data + (size-1),Data);
if swap goes from 'First to Last' and the 0th element is Other.Data?
6 - Why doesn't the commented out constructor work (I had to change size to mysize) - is assume this means regardless of the order I write them, the constructor will always call the allocation element first?
7 - Any other comments on my implementation? I know the code is useless but i'm just trying to illustrate a point.
class TBar
{
public:
//Swap Function
void swap(TBar &One, TBar &Two)
{
std::swap(One.b,Two.b);
std::swap(One.a,Two.a);
}
int a;
int *b;
TBar& operator=(TBar Other)
{
swap(Other,*this);
return (*this);
}
TBar() : a(0), b(new int) {} //We Always Allocate the int
TBar(TBar const &Other) : a(Other.a), b(new int)
{
std::copy(Other.b,Other.b,b);
*b = 22; //Just to have something
}
virtual ~TBar() { delete b;}
};
class TSuperFoo : public TBar
{
public:
int* Data;
int size;
//Swap Function for copy swap
void swap (TSuperFoo &One, TSuperFoo &Two)
{
std::swap(static_cast<TBar&>(One),static_cast<TBar&>(Two));
std::swap(One.Data,Two.Data);
std::swap(One.size,Two.size);
}
//Default Constructor
TSuperFoo(int mysize = 5) : TBar(), size(mysize), Data(new int[mysize]) {}
//TSuperFoo(int mysize = 5) : TBar(), size(mysize), Data(new int[size]) {} *1
//Copy Constructor
TSuperFoo(TSuperFoo const &Other) : TBar(Other), size(Other.size), Data(new int[Other.size]) // I need [Other.size]! not sizw
{
std::copy(Other.Data,Other.Data + size,Data); // Should this be (size-1) if std::copy is First -> Last? *2
}
//Assignment Operator
TSuperFoo& operator=(TSuperFoo Other)
{
swap(Other,(*this));
return (*this);
}
~TSuperFoo() { delete[] Data;}
};