Clone Objectives Describe how to make a copy of a reference type - - PDF document
Clone Objectives Describe how to make a copy of a reference type - - PDF document
Clone Objectives Describe how to make a copy of a reference type ICloneable interface Clone method Object.MemberwiseClone method Discuss special cases string field reference field inheritance 2 Motivation:
Objectives
2
- Describe how to make a copy of a reference type
– ICloneable interface – Clone method – Object.MemberwiseClone method
- Discuss special cases
– string field – reference field – inheritance
Motivation: reference type
- Classes are reference types
– instance is reference/object pair
3
class Person { string name int age; ... }
reference type
Person a = new Person("Ann", 25);
name age 25 a Ann
Motivation: reference assignment
- Assignment with reference types copies the reference
– results in aliasing – two references refer to same object
Person a = new Person("Ann", 25); Person b; b = a;
assign
name age 25 a Ann b
4
ICloneable
- Framework in place to copy instance
– can be useful for reference types – programmer chooses shallow or deep copy semantics
5
interface ICloneable {
- bject Clone();
}
cloning framework
Clone
- Class can support cloning
– implement ICloneable interface – code Clone method
class Person : ICloneable { public object Clone() { ... } ... }
Clone method
6
Using Clone
- Call Clone to create new object
– return type is object – cast to actual type
Person a = new Person("Ann", 25); Person b; b = (Person)a.Clone();
clone
7
MemberwiseClone
- Object MemberwiseClone method supports cloning
– allocates memory for type being cloned and does shallow copy – sufficient in simple cases – insufficient in complex situations
class Object { protected object MemberwiseClone() { ... } ... }
support for cloning
8
Implementing Clone
- Clone implementation typically uses MemberwiseClone
– additional work needed only if shallow copy not sufficient
class Person : ICloneable { public object Clone() { return MemberwiseClone(); } ... }
MemberwiseClone sufficient here
9
Result of Clone
- Clone results in new object
– with values copied from old object
Person a = new Person("Ann", 25); Person b; b = (Person)a.Clone();
clone
name age 25 b name age 25 a Ann
10
Clone and string
- Not necessary to clone string fields
– string is immutable – alias ok
11
name age 25 b name age 25 a Ann
Reference field
- Class may have reference field
12
class Student { int id; Transcript transcript; ... }
reference field
class Transcript { double gpa; int units; ... }
Object with reference field
- Object with reference field contains only reference
– refers to separate object
class Student { public Student(int id, double gpa, int units) { this.id = id; this.transcript = new Transcript(gpa, units); } ... } allocate object for reference field Student a = new Student(4000, 4.0, 50);
id 4000 transcript a gpa 4.0 units 50
13
Implementing Clone with reference field
- Clone of class with reference field more difficult
– use MemberwiseClone to get shallow copy – manually Clone reference field
class Student : ICloneable { public object Clone() { Student s = (Student)MemberwiseClone(); s.transcript = (Transcript)transcript.Clone(); return s; } ... } allocate memory, shallow copy clone reference field
14
Result of Clone with reference field
- Cloning object with reference field can clone referred objects
– to get deep copy
Student a = new Student(4000, 4.0, 50); Student b; b = (Student)a.Clone();
id 4000 transcript a gpa 4.0 units 50 id 4000 transcript b gpa 4.0 units 50
15
Cloning fields
- Reference field should support cloning
– otherwise difficult to clone entire object
Transcript supports Clone
class Transcript : ICloneable { double gpa; int units; public object Clone() { ... } ... }
16
Inheritance
- Class may use inheritance
class Person { string name; int age; ... }
inheritance
class Student : Person { int id; Transcript transcript; ... }
17
Derived object
- Object of derived type might be quite complicated
– contains fields of base – in addition to its own
Student a = new Student("Ann", 25, 4000, 4.0, 50);
name age 25 id 4000 transcript a gpa 4.0 units 50 Ann
18
Derived Clone
- Derived class Clone chains to base class Clone
– lets base allocate memory – then clones any of its own reference fields
class Student : Person, ICloneable { public object Clone() { Student s = (Student)base.Clone(); s.transcript = (Transcript)transcript.Clone(); return s; } ... } chain to base clone reference field
19
Base Clone
- Base class clone method
– allocates memory – clones any reference fields in base class
- Use MemberwiseClone to allocate memory
– correctly creates object of type being cloned
20
class Person : ICloneable { public object Clone() { return MemberwiseClone(); } ... }
MemberwiseClone sufficient here
Result of cloning derived object
- Clone of derived object yields new derived object
– both base and derived parts cloned
Student a = new Student("Ann", 25, 4000, 4.0, 50); Student b; b = (Student)a.Clone();
name age 25 id 4000 transcript a gpa 4.0 units 50 Ann name age 25 id 4000 transcript b gpa 4.0 units 50
21
Dynamically bound Clone
- Clone in inheritance hierarchy should be dynamically bound
– ensures correct version when called through base reference
Person a = new Student("Ann", 25, 4000, 4.0, 50); Person b; b = a.Clone();
must ensure Student Clone used
22
Virtual clone
- Make Clone virtual in inheritance hierarchy
– base Clone marked virtual – derived Clone marked override
class Person : ICloneable { public virtual object Clone() { ... } ... }
virtual in base
class Student : Person { public override object Clone() { ... } ... }
- verride in derived
23
Summary
24
- Clone provides way to perform deep copy
– must be implemented by programmer – object class provides some support
- Cloning can be tricky
– reference fields – inheritance