I have seen many examples of copy constructor for classes with member variables as pointer to int or char. Can someone advise on the right way of writing a copy constructor for a class A with a member ptrB which is a pointer to user defined class B please.
Is this correct:
class A {
private:
B *ptrB;
public:
A() { ptrB = new B; }
A(const A& other);
~A();
}
A::A(const A& other)
{
ptrB = new B;
*(ptrB) = *(other.ptrB);
}
and If ptrB was defined like this:
shared_ptr<B> ptrB;
then this?
A::A(const A& other)
{
ptrB(new B);
*(ptrB) = *(other.ptrB);
}
Thanks.
Since you tagged the post with "deep-copy" I assume you want the copy constructor to do that. The default copy constructor generated using shared_ptr does not deep copy.
I would suggest that there are two general forms for copying a pointer-like member.
Deep(const Deep& other): ptr(new T(*other.ptr)) {}
and
Shallow(const Shallow& other) = default;
Note, a shallow copy like that won't work for a unique_ptr. By design, unique_ptr prevents that.
Here is an example of each, showing the difference. Nb, using the raw version in practice could easily lead to a memory leak. The important point is that after the shallow copy, modifying the copy modifies the original.
#include <memory>
#include <iostream>
template<typename T, typename TPtr>
struct Deep
{
TPtr ptr;
Deep() : ptr(new T) {}
T get() const { return *ptr; }
void set(T t) { *ptr = t; }
Deep(const Deep& other): ptr(new T(*other.ptr)) {}
};
template<typename T, typename TPtr>
struct Shallow
{
TPtr ptr;
Shallow() : ptr(new T) {}
T get() const { return *ptr; }
void set(T t) { *ptr = t; }
Shallow(const Shallow& other) = default;
};
template<typename T>
using raw_ptr = T*;
template<typename T>
void test(const T& a1)
{
auto a2 = a1;
a2.set(a2.get() + 1);
std::cout << a1.get() << " " << a2.get() << std::endl;
}
using std::shared_ptr;
int main()
{
Deep<int, raw_ptr<int> > rawDeep;
rawDeep.set(1);
test(rawDeep);
Deep<int, shared_ptr<int> > sharedDeep;
sharedDeep.set(1);
test(sharedDeep);
Shallow<int, raw_ptr<int> > rawShallow;
rawShallow.set(1);
test(rawShallow);
Shallow<int, shared_ptr<int> > sharedShallow;
sharedShallow.set(1);
test(sharedShallow);
}
http://ideone.com/NltfUO
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With