Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

Virtual Copy Constructor ใน C++


บทนำ

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