Copy object - keep polymorphism
Try this:
class Super
{
public:
Super();// regular ctor
Super(const Super& _rhs); // copy constructor
virtual Super* clone() const {return(new Super(*this));};
}; // eo class Super
class Special : public Super
{
public:
Special() : Super() {};
Special(const Special& _rhs) : Super(_rhs){};
virtual Special* clone() const {return(new Special(*this));};
}; // eo class Special
Note that we have implemented a clone() function that Special (and any other derivative of Super) overrides to create the correct copy.
e.g:
Super* s = new Super();
Super* s2 = s->clone(); // copy of s
Special* a = new Special();
Special* b = a->clone(); // copy of a
EDIT: As other commentator pointed out, *this
, not this
. That'll teach me to type quickly.
EDIT2: Another correction.
EDIT3: I really should not post so quickly when in the middle of work. Modified return-type of Special::clone() for covariant return-types.
Copying a Polymorphic object in C++
This is still how we do stuff in C++ for polymorphic classes, but you don't need to do the explicit copy of members if you create a copy constructor (possibly implicit or private) for your objects.
class Base
{
public:
virtual Base* Clone() = 0;
};
class Derivedn : public Base
{
public:
//This is OK, its called covariant return type.
Derivedn* Clone()
{
return new Derivedn(*this);
}
private:
Derivedn(const Derivedn&) : ... {}
};
Is it possible to clone a polymorphic object without manually adding overridden clone method into each derived class in C++?
You can use this generic CRTP code
template <class Derived, class Base>
struct Clonable : Base {
virtual Base* do_clone() {
return new Derived(*static_cast<Derived*>(this));
}
Derived* clone() { // not virtual
return static_cast<Derived*>(do_clone());
}
using Base::Base;
};
struct empty {};
struct A : Clonable<A, empty> {};
struct B : Clonable<B, A> {};
It can be generalised to smart pointers and multiple bases if desired.
C# polymorphism with cloning
have your Loot class implement ICloneable
public abstract class Loot : ICloneable
{
public virtual object Clone()
{
Type type = this.GetType();
Loot newLoot = (Loot) Activator.CreateInstance(type);
//do copying here
return newLoot;
}
}
C++ Copying vector of pointers with polymorphism
For A* ptr = &B(77);
, B(77)
is a temporary object which will be destroyed when the expression finished, and then ptr
will become a dangled pointer.
For
A* CreateCopy()
{
A tmp = A(member); // tmp: member = 77, name = "Base"
return &tmp; // &tmp: member = 77, name = ""
}
tmp
is a local variable which will be destroyed when out of the scope of the function, that means CreateCopy()
will return a dangled pointer.
Is it possible to perform the copy without using the "new" operator? It seems like memory leaks are more likely to happen while using this operator.
You could use smart pointer to avoid manual memory management. Such as std::unique_ptr or std::shared_ptr.
Copy constructor in polymorphism in C#
You can use an overridden virtual Copy method instead of a copy constructor.
public class BaseClass
{
public BaseClass()
{
}
public virtual BaseClass ShallowCopy()
{
return new BaseClass();
}
public virtual string GetMSG()
{
return "Base";
}
}
public class DrivenClass : BaseClass
{
public string MSG { get; set; }
public DrivenClass(string msg)
{
MSG = msg;
}
public override BaseClass ShallowCopy() {
return new DrivenClass(this.MSG);
}
public override string GetMSG()
{
return MSG;
}
}
Then call it like this:
D = new DrivenClass("Driven");
B = D.ShallowCopy();
This will work because calling a virtual method always calls the actual overriden implementation in the subclass, even when called from the baseclass interface.
What is the purpose of copying an object in object oriented programming?
There are many situations where you might need to duplicate an object.
For convenience: When you create an object, you usually need to initialize it, either in the form of calling methods to set values, or in the form of passing parameters to the constructor. Sometimes, performing all this initialization might amount to a lot of work. If you want a new object B which only differs from another object A by a single value, then it may be easier to get a copy of A as B and change a single value of B, rather than to create B from scratch.
Because logic requires it: When a chess playing algorithm wants to make its next move, it may internally make many copies of the current board, modify each one of them with one of many possible moves that it may make, evaluate each one of the new boards using some heuristics, pick the best, and then use that as the new current board.
To be defensive: When a
Person
object is asked for itsDateOfBirth
, it may not necessarily return a reference to its ownDateOfBirth
, because someone might then alter theDate
object, thus altering the Person'sDateOfBirth
. So, thePerson
object is likely to return a defensive copy of itsDateOfBirth
.To take a snapshot: If I have a list of event observers to invoke, I might want to take a (shallow) snapshot copy of the list before starting to invoke the observers, because an observer may decide to unregister itself while I am processing the list, which will have disastrous consequences. (
ConcurrentModificationException
, look it up.)
How can I copy a templated instance with a virtual base class?
Traditionally, it's done by adding clone
method to the Base
:
struct Base {
virtual std::unique_ptr<Base> clone() const = 0;
virtual ~Base() = default;
};
CRTP can be used to automate overriding this method here:
template<class Child> struct Clonable: Base {
std::unique_ptr<Base> clone() const final {
auto &asChild = *static_cast<Child const *>(this);
return std::make_unique<Child>(asChild);
}
};
struct Foo: Clonable<Foo> {};
Deep Copy/Clone methods in a C# class hierarchy - Do I need a concrete implementation everywhere?
Could use an extension method and do incremental cloning
public static class DeepCopyExt
{
public static T DeepCopy<T>(this T item)
where T : ThingBase, new()
{
var newThing = new T();
item.CopyInto(newThing);
return newThing;
}
}
public abstract class ThingBase
{
public int A { get; set; }
public virtual void CopyInto(ThingBase target)
{
target.A = A;
}
}
public class ThingA : ThingBase
{
}
public class ThingB : ThingA
{
public int B { get; set; }
public override void CopyInto(ThingBase target)
{
var thingB = target as ThingB;
if(thingB == null)
{
throw new ArgumentException("target is not a ThingB");
}
thingB.B = B;
base.CopyInto(thingB);
}
}
class Program
{
static void Main(string[] args)
{
var b = new ThingB
{
A = 1,
B = 3
};
//c is ThingB
var c = b.DeepCopy();
var b1 = new ThingA
{
A = 1,
};
//c1 is ThingA
var c1 = b1.DeepCopy();
Debugger.Break();
}
}
Related Topics
How to Debug C++11 Code with Unique_Ptr in Ddd (Or Gdb)
Why Derive from a Concrete Class Is a Poor Design
Fseek Does Not Work When File Is Opened in "A" (Append) Mode
Casting to Void* and Back to Original_Data_Type*
Adding Quotes to Argument in C++ Preprocessor
What Is the Fastest Way to Compute Large Power of 2 Modulo a Number
Static Initialization and Destruction of a Static Library's Globals Not Happening with G++
Windows Named Pipe Support in Linux
Why Is It Not Possible to Overload the Ternary Operator
Virtual Functions Default Parameters
How to Suppress Specific Warnings in G++
Cmake Error: "Add_Subdirectory Not Given a Binary Directory"
Communication Between Native-App and Chrome-Extension
C++ Cmake (Add Non-Built Files)
Copy Constructor of Derived Qt Class