1. Deep copy and shallow copyA copy is usually referred to as copy or Clone (clone), and the copy of the object is a new object that duplicates an "exact" one from an existing object. Although they are all copied objects, different methods of replication, the new objects are not exactly the same, there are some differences within the object. There are two common copy methods, that is, deep copy and shallow copy, what is the difference between them? The Clone method for the Iclone interface is described in MSDN: in a deep copy, all objects are duplicates, whereas in a shallow copy, only the top-level objects are duplicates, and the objects below the top-level contain references. As can be seen, the deep copy and the shallow copy between the
the difference is whether the child objects are copied. How does that make sense? Here I verify the difference by using code with child objects. The first two types are defined: Student and classroom, where the student type contains classroom and enables both types to implement a custom deep copy interface (ideepcopy) and a shallow copy interface (ishallowcopy) respectively. The class diagram is as follows:
The definition code is as follows:
View Code/// <summary>
///Deep Copy Interface
/// </summary>
InterfaceIdeepcopy
{
ObjectDeepcopy ();
}
/// <summary>
///Shallow Copy interface
/// </summary>
InterfaceIshallowcopy
{
ObjectShallowcopy ();
}
/// <summary>
///Classroom Information
/// </summary>
classClassroom:ideepcopy, Ishallowcopy
{
PublicintRoomid =1;
PublicstringRoomname ="Room1";
PublicOverridestringToString ()
{
return"roomid="+ Roomid +"\troomname="+ Roomname;
}
PublicObjectDeepcopy ()
{
Classroom R =NewClassroom ();
R.roomid = This. Roomid;
R.roomname = This. Roomname;
returnR
}
Public ObjectShallowcopy ()
{
//return directly using the built-in shallow copy method
return This. MemberwiseClone ();
}
}
classStudent:ideepcopy, Ishallowcopy
{
//to simplify, use the public field
PublicstringName;
PublicintAge;
//custom types, assuming that each student has only one classroom
PublicClassroom =NewClassroom ();
PublicStudent ()
{
}
PublicStudent (stringNameintAge
{
This. name = name;
This. Age = age;
}
PublicObjectDeepcopy ()
{
Student s =NewStudent ();
S.name = This. Name;
S.age = This. Age;
S.room = (Classroom) This. Room.deepcopy ();
returnS
}
PublicObjectShallowcopy ()
{
return This. MemberwiseClone ();
}
PublicOverride stringToString ()
{
return"Name:"+ Name +"\tage:"+ Age +"\ t"+ room.tostring ();
}
}pastingpasting
Test code:
View CodeStudent S1 =NewStudent ("Vivi", -);
Console.WriteLine ("s1=["+ S1 +"]");
Student s2 = (Student) s1. Shallowcopy ();
//Student s2 = (Student) s1. Deepcopy ();
Console.WriteLine ("s2=["+ s2 +"]");//here s2 and S1 content are the same
Console.WriteLine ("-----------------------------");
//Modify the contents of a S2
S2. Name ="Tianyue";
S2. Age = -;
S2. Room.roomid =2;
S2. Room.roomname ="Room2";
Console.WriteLine ("s1=["+ S1 +"]");
Console.WriteLine ("s2=["+ s2 +"]");
//print two objects again to compare
Console.ReadLine ();
Operation Result:
A.shallowcopys1=[name:vivi age:28 roomid=1 Roomname=room1]
S2=[name:vivi age:28 roomid=1 Roomname=room1]
-------------------------------------------------------------s1=[name:vivi age:28 roomid=2 roomname=room2]
S2=[name:tianyue age:25 roomid=2 Roomname=room2]
B.deepcopys1=[name:vivi age:28 roomid=1 Roomname=room1]
S2=[name:vivi age:28 roomid=1 Roomname=room1]
-----------------------------
s1=[name:vivi age:28 roomid=1 roomname=room1]
S2=[name:tianyue age:25 roomid=2 Roomname=room2] from the above results, it can be seen that the two objects in the deep copy are completely "separated", changing one without affecting the other, while the two objects are not fully "divided To change the contents of the top-level object without affecting the other object, but changing the contents of the child object, the two objects are changed at the same time. The result of this difference is whether copying the memory or copying the pointer when copying the sub-object. A deep copy allocates a memory space for a sub-object and copies the contents of it; a shallow copy simply points the pointer to the original child object. As follows:
2. Shallow copy and assignment operationThe assignment operation in most object-oriented languages is to pass a reference, that is, to change the object's pointer address, without duplicating memory or doing any copy operations. The difference between a shallow copy and an assignment operation is
whether the top-level objects are replicated or not. Of course, there are exceptions, such as overloaded assignment operators (assignment operator) in a type definition, or some type conventions passing by value, like struct and enum types in C #. The assignment operation is as follows:
3.c++ Copy ConstructorsUnlike other object-oriented languages, C + + allows users to choose how custom objects are passed: value passing and reference passing. When a value is passed, an object copy is used, such as passing parameters by value, and the compiler needs to copy an object to prevent the original object from being destroyed in the function body. For this reason, C + + provides a copy constructor to implement this copy behavior, and the copy constructor is a special constructor used to construct and initialize other objects based on the same class. Its only argument is a reference type and is immutable, usually defined as X (const x&). In the copy constructor, the user can define whether the copy behavior of the object is a deep copy or a shallow copy, and if the user does not implement their own copy constructor, then the compiler provides a default implementation that uses a bitwise copy (bitwise copy), which is the shallow copy described in this article. When is the constructor called? Typically the following three cases require copying an object, at which point the copy constructor is called.
1. An object is passed in the function body in the way of value passing
2. An object is returned from the function in the way that the value is passed
3. An object needs to be initialized with another object
4.c# memberwiseclone and ICloneable interfaceLike the copy constructors in C + +, C # also provides a shallow copy of the default implementation for each object, but in C # there is no copy constructor, but rather a memberwiseclone method in the top-level object. The MemberwiseClone method creates a shallow copy by creating a new object and then copying the non-static field of the current object to the new object. Is there a default deep copy implementation? Of course not, because all the objects involved in the copy are required to define their own deep copy behavior. C + + requires the user to implement the copy constructor, overriding the default shallow copy, C # is different, C # (specifically, the. NET Framework, not the C # language) provides the ICloneable interface, which contains a member Clone, which is used to support the addition of MemberwiseClone A clone other than the provided clone. C + + cannot determine whether a sub-object implements a deep copy or a shallow copy by copying the constructor, while C # provides a icloneable interface for a user-defined deep copy behavior through an interface that enforces the binding of all participating copies, which, personally, is a small bit of C # for c+ + improvements.
5. Deep copy strategy and implementationThe key point of a deep copy is to make sure that all the objects involved in the copy provide their own deep-copy implementations, whether it's a C + + copy constructor or C # ICloneable interface, which is actually a copy of the Convention. With the prior agreement, in order to constrain the unity of implementation, so the key lies in the design. But occasionally also in the late to think of deep copy, how to do? You can't always modify all the previous implementations. Is there a way to make deep copies directly from the top class without caring for the inner sub-objects? Can make a all-purpose deep copy method, when you want to use the time immediately, regardless of the previous design. This "embracing" method, the difficulty is that the implementation must automatically obtain the child object information, respectively, to achieve a deep copy of the sub-object. C + + is more difficult. NET's reflection mechanism makes implementation easier. However, such a method, although generic, actually destroys the package, and does not conform to the "each class is responsible for itself" design principles. Based on. NET's reflection mechanism, previously wrote a common serialization method, can now be taken, first serialized, and then deserialized back, that is, a deep copy, the sample code is as follows: Deep copy sample code:
View Code#regionICloneable Members
/// <summary>
///the copy here is a deep copy, which is implemented in order to simplify, using serialization and deserialization.
/// </summary>
/// <returns>Deep Copy Objects</returns>
PublicObjectClone ()
{
Student stu =NewStudent ();
Xmlstoragehelper helper =NewXmlstoragehelper ();
stringStrxml = Helper. ConvertToString ( This);
Helper. Loadfromstring (Stu, strxml);//to assign a value from an XML string
returnStu
}
#endregion
Analysis of C # deep copy and shallow copy