บทนำ
Copy Constructor: Constructor พิเศษสร้างออบเจกต์เป็นสำเนาของออบเจกต์อื่น
Virtual Function: ฟังก์ชันใน Base class ที่ถูก Override ใน Derived class
Virtual Copy Constructor: ไม่มีจริงใน C++ แต่ใช้ pattern เรียกว่า Virtual Constructor Idiom หรือ Clone Pattern เพื่อสร้างสำเนาออบเจกต์ได้ใน Runtime โดยไม่ต้องรู้ชนิดจริงของออบเจกต์
หลักการทำงาน
Base class ประกาศ virtual function clone() และ create() แล้ว Derived class implement เอง
ตัวอย่าง: สร้างรูปทรง (Square, Circle, Rectangle) แบบ Dynamic
#include <iostream>
using namespace std;
class Figure {
public:
Figure() {}
virtual ~Figure() {}
virtual void ChangeAttributes() = 0;
static Figure* Create(int id);
virtual Figure* Clone() = 0;
};
class Square : public Figure {
public:
Square() { cout << "Square created\n"; }
Square(const Square&) {}
~Square() {}
void ChangeAttributes() {
int a; cout << "Side of square: "; cin >> a;
cout << "Area: " << a*a << endl;
}
Figure* Clone() { return new Square(*this); }
};
class Circle : public Figure {
public:
Circle() { cout << "Circle created\n"; }
Circle(const Circle&) {}
~Circle() {}
void ChangeAttributes() {
int r; cout << "Radius: "; cin >> r;
cout << "Area: " << 3.14*r*r << endl;
}
Figure* Clone() { return new Circle(*this); }
};
class Rectangle : public Figure {
public:
Rectangle() { cout << "Rectangle created\n"; }
Rectangle(const Rectangle&) {}
~Rectangle() {}
void ChangeAttributes() {
int a,b; cout << "Dimensions: "; cin >> a >> b;
cout << "Area: " << a*b << endl;
}
Figure* Clone() { return new Rectangle(*this); }
};
Figure* Figure::Create(int id) {
if (id == 1) return new Square;
else if (id == 2) return new Circle;
else return new Rectangle;
}
class User {
Figure* figure;
public:
User() : figure(0) {
int input;
cout << "Enter ID (1=Square, 2=Circle, 3=Rectangle): ";
cin >> input;
while (input < 1 || input > 3) {
cout << "Enter 1, 2 or 3 only: "; cin >> input;
}
figure = Figure::Create(input);
}
~User() { if (figure) delete figure; }
void Action() {
Figure* newFig = figure->Clone();
newFig->ChangeAttributes();
delete newFig;
}
};
int main() {
User* user = new User();
user->Action();
delete user;
return 0;
}
ผลลัพธ์ตัวอย่าง
Enter ID (1=Square, 2=Circle, 3=Rectangle): 2 Circle created Radius: 3 Area: 28.26