mwhite
mwhite

Reputation: 47

How to implement deep and shallow copy constructors without using a boolean parameter?

I have the following class:

class A {
    int small;
    std::shared_ptr<B> big;
};

Here, B is a class whose objects are expected to have a very large size. In my program, I have an original object of class A and then make multiple copies of it, then copies of the copies, etc.

Sometimes, I need to make a deep copy, because all members might be modified. Other times, I know that I won't make any changes to A::big and thus I would like to copy only the pointer in order to save resources (a profiler showed me that this is a bottleneck).

Currently, I have the following:

A(const A& other, bool doDeepCopy): 
    small{other.small}, big{doDeepCopy ? std::make_shared<B>(*other.big) : other.big} {}

I am aware that using bool parameters is considered bad style, but I don't know what else to do. The default copy constructor makes a shallow copy, and I could encapsulate it within a function A A::makeShallowCopy(). But how should the other constructor look like? The only input it needs is an object of type A, but I obviously cannot have two functions with the same signature.

Upvotes: 3

Views: 215

Answers (1)

m88
m88

Reputation: 1988

Assuming B has a copy constructor, just add:

class A {
    int small;
    std::shared_ptr<B> big;

public:
    A clone() const {
        return { small, std::make_shared<B>(*big) };
    }
};

So clone() becomes the only way to deep-copy your data.


That's the method used in OpenCV and Eigen for matrices: the copy is shallow by default, and an explicit call to replicate() or clone() is required for deep copies.

Upvotes: 2

Related Questions