How to Clone Object in C++? or Is There Another Solution

How to clone object in C++ ? Or Is there another solution?

The typical solution to this is to write your own function to clone an object. If you are able to provide copy constructors and copy assignement operators, this may be as far as you need to go.

class Foo
{
public:
Foo();
Foo(const Foo& rhs) { /* copy construction from rhs*/ }
Foo& operator=(const Foo& rhs) {};
};

// ...

Foo orig;
Foo copy = orig; // clones orig if implemented correctly

Sometimes it is beneficial to provide an explicit clone() method, especially for polymorphic classes.

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

class Foo : public Interface
{
public:
Interface* clone() const { return new Foo(*this); }
};

class Bar : public Interface
{
public:
Interface* clone() const { return new Bar(*this); }
};

Interface* my_foo = /* somehow construct either a Foo or a Bar */;
Interface* copy = my_foo->clone();

EDIT: Since Stack has no member variables, there's nothing to do in the copy constructor or copy assignment operator to initialize Stack's members from the so-called "right hand side" (rhs). However, you still need to ensure that any base classes are given the opportunity to initialize their members.

You do this by calling the base class:

Stack(const Stack& rhs) 
: List(rhs) // calls copy ctor of List class
{
}

Stack& operator=(const Stack& rhs)
{
List::operator=(rhs);
return * this;
};

Deep cloning objects

Whereas one approach is to implement the ICloneable interface (described here, so I won't regurgitate), here's a nice deep clone object copier I found on The Code Project a while ago and incorporated it into our code.
As mentioned elsewhere, it requires your objects to be serializable.

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

/// <summary>
/// Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>
public static class ObjectCopier
{
/// <summary>
/// Perform a deep copy of the object via serialization.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>A deep copy of the object.</returns>
public static T Clone<T>(T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", nameof(source));
}

// Don't serialize a null object, simply return the default for that object
if (ReferenceEquals(source, null)) return default;

using var Stream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}

The idea is that it serializes your object and then deserializes it into a fresh object. The benefit is that you don't have to concern yourself about cloning everything when an object gets too complex.

In case of you prefer to use the new extension methods of C# 3.0, change the method to have the following signature:

public static T Clone<T>(this T source)
{
// ...
}

Now the method call simply becomes objectBeingCloned.Clone();.

EDIT (January 10 2015) Thought I'd revisit this, to mention I recently started using (Newtonsoft) Json to do this, it should be lighter, and avoids the overhead of [Serializable] tags. (NB @atconway has pointed out in the comments that private members are not cloned using the JSON method)

/// <summary>
/// Perform a deep Copy of the object, using Json as a serialization method. NOTE: Private members are not cloned using this method.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T CloneJson<T>(this T source)
{
// Don't serialize a null object, simply return the default for that object
if (ReferenceEquals(source, null)) return default;

// initialize inner objects individually
// for example in default constructor some list property initialized with some values,
// but in 'source' these items are cleaned -
// without ObjectCreationHandling.Replace default constructor values will be added to result
var deserializeSettings = new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace};

return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings);
}

How to Clone Objects

Is there a way to shortcut this at all?

No, not really. You'll need to make a new instance in order to avoid the original from affecting the "copy". There are a couple of options for this:

  1. If your type is a struct, not a class, it will be copied by value (instead of just copying the reference to the instance). This will give it the semantics you're describing, but has many other side effects that tend to be less than desirable, and is not recommended for any mutable type (which this obviously is, or this wouldn't be an issue!)

  2. Implement a "cloning" mechanism on your types. This can be ICloneable or even just a constructor that takes an instance and copies values from it.

  3. Use reflection, MemberwiseClone, or similar to copy all values across, so you don't have to write the code to do this. This has potential problems, especially if you have fields containing non-simple types.

How do I clone a generic list in C#?

You can use an extension method.

static class Extensions
{
public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
{
return listToClone.Select(item => (T)item.Clone()).ToList();
}
}

How do you do a deep copy of an object in .NET?

Important Note

BinaryFormatter has been deprecated, and will no longer be available in .NET after November 2023. See BinaryFormatter Obsoletion Strategy


I've seen a few different approaches to this, but I use a generic utility method as such:

public static T DeepClone<T>(this T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;

return (T) formatter.Deserialize(ms);
}
}

Notes:

  • Your class MUST be marked as [Serializable] for this to work.

  • Your source file must include the following code:

     using System.Runtime.Serialization.Formatters.Binary;
    using System.IO;

How to clone an object into a subclass object?

There is no means of doing this automatically built into the language...

One option is to add a constructor to class B that takes a class A as an argument.

Then you could do:

B newB = new B(myA);

The constructor can just copy the relevant data across as needed, in that case.

How to clone object with a different Primary Key

I'm not sure what App.RealmDB does under the hood, but using the out-of-the-box Realm API, what you want to achieve can be done by simply adding the CartLines from the original to the updated object:

// Assume want to change Id from 1 to 2
var realm = Realm.GetInstance();
var original = realm.Find<Cart_Record>(1);

var updated = new Cart_Record { ID = 2 }; // other properties must be copied here
foreach (var cart in original.CartLines)
{
updated.CartLines.Add(cart);
}

realm.Write(() =>
{
realm.Remove(original);
realm.Add(updated);
});

// updated now has all the original's CartLines

Creating a copy of an object in C#

There is no built-in way. You can have MyClass implement the IClonable interface (but it is sort of deprecated) or just write your own Copy/Clone method. In either case you will have to write some code.

For big objects you could consider Serialization + Deserialization (through a MemoryStream), just to reuse existing code.

Whatever the method, think carefully about what "a copy" means exactly. How deep should it go, are there Id fields to be excepted etc.

What is the most efficient way to deep clone an object in JavaScript?

Native deep cloning

There's now a JS standard called "structured cloning", that works experimentally in Node 11 and later, will land in browsers, and which has polyfills for existing systems.

structuredClone(value)

If needed, loading the polyfill first:

import structuredClone from '@ungap/structured-clone';

See this answer for more details.

Older answers

Fast cloning with data loss - JSON.parse/stringify

If you do not use Dates, functions, undefined, Infinity, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays or other complex types within your object, a very simple one liner to deep clone an object is:

JSON.parse(JSON.stringify(object))

const a = {
string: 'string',
number: 123,
bool: false,
nul: null,
date: new Date(), // stringified
undef: undefined, // lost
inf: Infinity, // forced to 'null'
re: /.*/, // lost
}
console.log(a);
console.log(typeof a.date); // Date object
const clone = JSON.parse(JSON.stringify(a));
console.log(clone);
console.log(typeof clone.date); // result of .toISOString()


Related Topics



Leave a reply



Submit