Copy constructor
ภูวเดช นามไพร 650710578

Constructor :
เป็นวิธีพิเศษที่ใช้ในการกำหนดค่าเริ่มต้นของอ็อบเจ็กต์ จะถูกเรียกใช้เมื่อมีการสร้างอ็อบเจ็กต์ของคลาส และยังสามารถใช้กำหนดค่าเริ่มต้นให้กับฟิลด์ได้
Syntax:
class Person {
public string Name { get; set; }
public int Age { get; set;}
//Parameterized Constructor
public Person(string name, int age) {
Name = name;
Age = age;
}
}
Copy Constructor:
เป็นเครื่องมือที่ช่วยให้เราสร้างวัตถุใหม่โดยการคัดลอกข้อมูลจากวัตถุที่มีอยู่แล้ว ซึ่งเป็นประโยชน์ในการสร้างสำเนาของวัตถุหรือการหลีกเลี่ยงการแก้ไขข้อมูลของวัตถุต้นฉบับ และ C# ไม่ได้มี Copy Constructor ที่สร้างมาให้โดยอัตโนมัติเหมือนภาษา C++ เราต้องสร้าง Copy Constructor ขึ้นมาเองตามความต้องการของโปรแกรม
Syntax:
class Person {
public string Name { get; set; }
public int Age { get; set; }
//copy constructor
public Person(Person other) {
Name = other.Name;
Age = other.Age;
}
}
ตัวอย่าง:
// C# Program to illustrate the use
// of Copy constructor
using System;
namespace copyConstructorExample {
class Vehicle {
// variables
private string name;
private string color;
private int quantity;
// Copy constructor
public Vehicle(Vehicle a)
{
name = a.name;
color = a.color;
quantity = a.quantity;
}
// Parameterized constructor
public Vehicle(string name, string color, int quantity)
{
this.name = name;
this.color = color;
this.quantity = quantity;
}
// Get details of Vehicles
public string DetailsofVehicle{
get{
return "Type: " + name.ToString() +
"\nColor: " + color.ToString() +
"\nQuantity: " + quantity.ToString();
}
}
// Main Method
public static void Main(){
// Create a new object.
Vehicle v1 = new Vehicle("Bike", "Black", 40);
// here is v1 details are copied to v2.
Vehicle v2 = new Vehicle(v1);
Console.WriteLine(v2.DetailsofVehicle);
}
}
}
ความแตกต่างระหว่าง Shallow Copy และ Deep Copy

Shallow copy :
คัดลอกแค่ "ที่อยู่" ของข้อมูล ไม่ได้คัดลอกข้อมูลจริงๆ
เหมาะสำหรับวัตถุที่ไม่ซับซ้อน หรือเมื่อต้องการให้วัตถุที่คัดลอกมาอ้างอิงข้อมูลเดียวกับวัตถุต้นฉบับ เร็วกว่า deep copy เนื่องจากไม่มีการจัดสรรหน่วยความจําใหม่
class ShallowCopy : ICloneable
{
public int I {get;set;}
public int J {get;set;}
//method for cloning object
public object Clone()
{
return this.MemberwiseClone();
}
}
class Demo
{
public static void Main()
{
ShallowCopy obj=new ShallowCopy();
Console.WriteLine(“--------before Shellow Clopy------”);
ShallowCopy objClone=obj;
obj.I=10;// setting obj value after cloning..
Console.WriteLine(“objvalue : {0} \t Clone value : {1}”,obj.I,objClone.I=10);
Console.WriteLine(“--------after Shellow Copy------”);
ShallowCopy objClone2=(ShallowCopy)obj.Clone(); // cast object to //ShallowCopy
obj.I=1000; // MemberwiseClone() will not use this reference..
Console.WriteLine(“after using MemberwiseClone() Clone() method :{0}”,objClone2.I);
}
}
Deep copy:
คัดลอกทั้ง "ที่อยู่" และ "ข้อมูล" ทำให้ได้วัตถุใหม่ที่แยกจากกันจริงๆ
เหมาะสำหรับวัตถุที่ซับซ้อน มีหลายชั้น หรือเมื่อต้องการให้วัตถุที่คัดลอกมาเป็นอิสระจากวัตถุต้นฉบับ แต่จะช้ากว่า shallow copy เนื่องจากมีการจัดสรรหน่วยความจําใหม่
class ReferenceType
{
public int RFT { get; set; }
}
class ShallowCopy : ICloneable
{
public int I { get; set; }
public int J { get; set; }
public ReferenceType K = new ReferenceType();
//Method updated for reference type ..
public object Clone()
{
// Shalllow Copy..
ShallowCopy SC = (ShallowCopy)this.MemberwiseClone();
// Deep copy...
ReferenceType RT = new ReferenceType();
RT.RFT = this.K.RFT;
SC.K = RT;
return SC;
}
public static void Main(String[] args)
{
ShallowCopy obj = new ShallowCopy();
obj.K.RFT = 100;
ShallowCopy objclone = (ShallowCopy)obj.Clone();
obj.K.RFT = 200; // make changes in obj.
Console.WriteLine(objclone.K.RFT);
}
}
เปรียบเทียบ copy constructor ของ C# กับภาษา Java/C/Python
C:

ภาษา C ไม่มี Copy Constructor เพราะไม่ได้เป็นภาษาเชิงวัตถุ (object-oriented) แบบเต็มรูปแบบ แต่สามารถทำการคัดลอก struct หรือ object แบบทำเองได้โดยใช้การคัดลอก field ทีละตัว หรือใช้ฟังก์ชัน
Shallow copy:
การคัดลอก primitive types จากตัวแปรหนึ่งไปยังอีกตัวแปรหนึ่ง แต่ถ้าตัวแปรนั้นเป็น pointer จะทำการคัดลอกเพียง address ของ object ที่ pointer นั้นชี้อยู่ ดังนั้นทั้งต้นฉบับและตัวคัดลอกจะใช้ object เดียวกันในหน่วยความจำ
#include <stdlib.h>
#include <string.h>
typedef struct student
{
char *name;
int age;
}student;
int main()
{
student t1;
t1.name = (char*)malloc(30);
strcpy(t1.name, "John");
t1.age = 22;
student t2 = t1;
printf("%s %d", t2.name, t2.age);
if (t1.name != NULL)
{
free(t1.name);
t1.name = NULL;
}
return 0;
}
Deep copy:
การคัดลอกทั้งตัวแปร primitive และ object ที่ pointer ชี้ไป โดยการจัดสรร allocate new memory และคัดลอกข้อมูลที่อยู่ในหน่วยความจำเก่าไปยังหน่วยความจำใหม่ ทำให้ object ที่คัดลอกมามีความเป็นอิสระจาก object ต้นฉบับ
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Student
{
char *name;
int age;
}Student;
int main(int argc, char *argv[])
{
Student std1;
Student std2;
std1.name = (char *)malloc(10);
std1.age = 20;
strcpy(std1.name, "John");
printf("std1->name: %s, age: %d\n", std1.name, std1.age);
std2 = std1;
std2.name = (char *)malloc(10);
strcpy(std2.name, std1.name);
printf("std2->name: %s, age: %d\n", std2.name, std2.age);
free(std1.name);
free(std2.name);
return 0;
}
ตัวอย่าง C เทียบ copy constructor กับ C#
C#:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(Person other) // Copy constructor
{
Name = other.Name;
Age = other.Age;
}
}
C:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *name;
int age;
} Person;
Person* copyPerson(Person *person) {
Person *newPerson = (Person*)malloc(sizeof(Person));
if (newPerson == NULL) {
return NULL;
}
newPerson->name = (char*)malloc(strlen(person->name) + 1);
strcpy(newPerson->name, person->name);
newPerson->age = person->age;
return newPerson;
}
Java:

ภาษา Java ไม่มี constructor สำหรับการคัดลอกโดยตรงเหมือนใน C++ หรือ C# แต่สามารถสร้าง Copy Constructor เองได้ โดยจะเป็นวิธีการสร้างวัตถุใหม่ โดยการคัดลอกค่าจากวัตถุที่มีอยู่แล้วมาใช้
Shallow copy:
การคัดลอกเฉพาะ primitive types และreferences ของ object แต่ไม่คัดลอกตัว object ที่ถูกอ้างอิง ทำให้ object ที่คัดลอกทั้งคู่ชี้ไปยัง object เดียวกันในหน่วยความจำ
class ABC
{
// Instance variable of the class ABC
int x = 30;
}
public class ShallowCopyExample
{
// Main method
public static void main(String argvs[])
{
// Creating an object of the class ABC
ABC obj1 = new ABC();
// It will copy the reference, not the value
ABC obj2 = obj1;
// Updating the value to 6 using the reference variable obj2
obj2.x = 6;
// Printing the value of x using reference variable obj1
System.out.println("The value of x is: " + obj1.x);
}
}
Deep copy:
การคัดลอกทั้งค่าของตัวแปร primitive และการสร้างสำเนาของ object ที่ถูกอ้างอิงใหม่ทั้งหมด ทำให้ object ต้นฉบับและ object ที่ถูกคัดลอกไม่มีการแชร์ข้อมูลร่วมกัน ทุกส่วนของ object จะถูกคัดลอกอย่างอิสระ
class ABC
{
// Instance variable of the class ABC
int x = 30;
}
public class DeepCopyExample
{
// Main method
public static void main(String argvs[])
{
// Creating an object of the class ABC
ABC obj1 = new ABC();
// Creating another object of the class ABC for deep copy
ABC obj2 = new ABC();
// Updating the value to 6 using the reference variable obj2
obj2.x = 6;
// Printing the value of x using reference variable obj1
System.out.println("The value of x is: " + obj1.x);
}
}
ตัวอย่าง Java เทียบ copy constructor กับ C#
C#:
class Person {
public string Name { get; set; }
public int Age { get; set; }
// Copy Constructor
public Person(Person other) {
Name = other.Name;
Age = other.Age;
}
}
Java:
class Person {
String name;
int age;
// Copy Constructor
public Person(Person other) {
this.name = other.name;
this.age = other.age;
}
}
Python:

ภาษา Python ไม่มี copy constructor แบบที่พบใน C++ หรือ Java แต่วิธีการสร้างวัตถุใหม่โดยใช้ข้อมูลจากวัตถุที่มีอยู่แล้ว ใน Python, __init__
method ทำหน้าที่เป็นตัวสร้างวัตถุ และ Copy Constructor สามารถสร้างได้โดยการกำหนดวิธีการที่มีรูปแบบเฉพาะ
Shallow copy:
สร้างวัตถุใหม่ แต่แทนที่จะคัดลอกองค์ประกอบของวัตถุดั้งเดิม จะคัดลอกอ้างอิงไปยังวัตถุเหล่านั้น ซึ่งหมายความว่าการเปลี่ยนแปลงที่ทำกับวัตถุที่ฝังอยู่ (nested objects) ในวัตถุที่คัดลอกมาจะสะท้อนไปยังวัตถุดั้งเดิมและในทางกลับกัน ใน Python โมดูล copy
และมีเมธอด copy()
import copy
class ShallowCopyExample:
def __init__(self, data):
self.data = data
def __str__(self):
return f"Original Object: {self.data}"
def shallow_copy(self):
return copy.copy(self)
# Example usage
original_object = ShallowCopyExample([1, 2, 3])
copy_object = original_object.shallow_copy()
print(original_object)
print(copy_object)
# Modify the copied object
copy_object.data.append(4)
# Changes reflected in the original object
print(original_object)
print(copy_object)
Deep copy:
โดยสร้างวัตถุใหม่และคัดลอกวัตถุย่อยทั้งหมดแบบเรียกซ้ำ (recursively) เพื่อให้แน่ใจว่าการเปลี่ยนแปลงในวัตถุที่คัดลอกมาไม่ส่งผลกระทบต่อวัตถุดั้งเดิม โมดูล copy
ของ Python และยังมีเมธอด deepcopy()
import copy
class DeepCopyExample:
def __init__(self, data):
self.data = data
def __str__(self):
return f"Original Object: {self.data}"
def deep_copy(self):
return copy.deepcopy(self)
# Example usage
original_object = DeepCopyExample([1, [2, 3], 4])
copy_object = original_object.deep_copy()
print(original_object)
print(copy_object)
# Modify the copied object
copy_object.data[1].append(99)
# Changes not reflected in the original object
print(original_object)
print(copy_object)
ตัวอย่าง Python เทียบ copy constructor กับ C#
C#:
class Person {
public string Name { get; set; }
public int Age { get; set; }
// Copy Constructor
public Person(Person other) {
Name = other.Name;
Age = other.Age;
}
}
Person person1 = new Person { Name = "Alice", Age = 30 };
Person person2 = new Person(person1); // Copy constructor
Python:
import copy
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# Shallow Copy
person1 = Person("Alice", 30)
person2 = copy.copy(person1) # Shallow copy
# Deep Copy
person3 = copy.deepcopy(person1) # Deep copy
Video:
Slide:
Reference:
w3schools. (n.d.). C# Constructors.
ankita_saini. (04 Dec, 2021). C# | Copy Constructor.
Anupam Singh. (04 Feb, 2022).Shallow Copy and Deep Copy Using C#.
OpenGenus Tech Review Team. (n.d.). Copy struct in C [Shallow & Deep Copy].
Javatpoint. (n.d.). Shallow Copy Vs. Deep Copy in Java.
GeeksforGeeks.(13 Feb, 2024). Copy Constructor in Python.
Microsoft. (03/12/2024). How to write a copy constructor (C# Programming Guide).
Last updated