Sadhu
Sadhu

Reputation: 57

How to take a backup/Clone of object in c++

I have a class SRecord and object like this in C++

SRecord* CurrentCmnd;

CurrentCmnd = theStack->Pop(dig, operation1, resp_sol);

I would like to backup the CurrentCmd here

CurrentCmnd = theStack->Pop(dig, operation2, resp_sol);

After this operation I would like to use the CurrentCmnd which returns from the first Pop operation so that I can perform other checks on CurrentCmnd.

How can I take a back up of the above CurrentCmnd before Popping the second element from the stack.

Also want to mention that, I cannot inherit the SRecord Class, cannot use copy constructor.

I am looking for the solution something like below

 CurrentCmnd = theStack->Pop(dig, operation1, resp_sol);

Backup of CurrentCmnd.

SRecord* Temp_CurrentCmnd = CurrentCmnd;

CurrentCmnd = theStack->Pop(dig, operation2, resp_sol);

CurrentCmnd = Temp_CurrentCmnd;

Upvotes: 2

Views: 794

Answers (1)

Daniel Trugman
Daniel Trugman

Reputation: 8511

Here are some possible ways to achieve that, all methods assume the class has a copy constructor

Simply using a copy constructor

You could just use it to create a copy on-the-fly.

Creating a dynamically allocated copy (don't forget to free the memory once you are done with it):

SRecord * copy = new SRecord(*CurrentCmnd);

Creating a local copy (this copy will exists only throughout the scope of the method):

SRecord copy(*CurrentCmd);

Adding a clone method to the object

A clean way to implement this to is to add the following method to SRecord:

class SRecord {
     public:
         SRecord * createBackup() { return new Object(*this); }
}

Then you can just call:

SRecord * CurrentCmndBackup = CurrentCmnd->createBackup();

Don't forget to free the backup when you're done with it :)

Generic implementation

In my projects, I usually add this method to some base class from which I can inherit later. It looks like this:

class Cloneable {
     public:
         virtual Cloneable * clone() = 0;
}

class SRecord : public Cloneable {
     public:
         virtual Cloneable * clone() { return new SRecord(*this); }
}

Smart Pointer implementation

An even cleaner implementation uses smart pointers. In most of my projects I found these objects to be something I'd like to pass to other modules down the road, so I used shared pointers, but a unique pointer implementation is also legit.

Here is how it looks:

class Cloneable {
    public:
        using Sptr = std::shared_ptr<Cloneable>;
        virtual Sptr clone() = 0;
};

class SRecord : public Cloneable {
    public:
        using Sptr = std::shared_ptr<SRecord>;
        virtual Cloneable::Sptr clone() { return std::static_pointer_cast<Cloneable>(std::make_shared<SRecord>(*this)); }
};

int main()
{
    SRecord::Sptr a = std::make_shared<SRecord>();
    SRecord::Sptr b = std::static_pointer_cast<SRecord>(a->clone());
}

Templated implementation

As suggested, an additional implementation is using a templated clone method that is not part of any object:

template < typename T >
std::shared_ptr<T> clone(const T & obj) {
    return std::make_shared<T>(obj);
}

Upvotes: 3

Related Questions