Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Hàm tạo sao chép ảo (Virtual Copy Constructor) trong C++

C++ không hỗ trợ constructor ảo, nhưng có thể mô phỏng bằng idiom Virtual Copy Constructor (hay còn gọi là Clone Pattern) sử dụng hàm ảo clone().

Vấn đề: Cần tạo bản sao đối tượng khi chỉ biết kiểu cơ sở (base class) tại runtime.

Giải pháp:

  • Base class khai báo pure virtual clone() trả về con trỏ base.
  • Derived class override clone() trả về new Derived(*this).
  • Sử dụng: Base* copy = obj->clone();

Thường kết hợp với create() static factory method.

Ví dụ minh họa (Hình học)

#include <iostream>
using namespace std;

class Figure {
public:
    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"; }
    void changeAttributes() override {
        int a; cout << "Canh vuong: "; cin >> a;
        cout << "Dien tich: " << a*a << endl;
    }
    Figure* clone() override { return new Square(*this); }
};

class Circle : public Figure {
public:
    Circle() { cout << "Circle created\n"; }
    void changeAttributes() override {
        int r; cout << "Ban kinh: "; cin >> r;
        cout << "Dien tich: " << 3.14*r*r << endl;
    }
    Figure* clone() override { return new Circle(*this); }
};

class Rectangle : public Figure {
public:
    Rectangle() { cout << "Rectangle created\n"; }
    void changeAttributes() override {
        int a,b; cout << "Canh hcn: "; cin >> a >> b;
        cout << "Dien tich: " << a*b << endl;
    }
    Figure* clone() override { return new Rectangle(*this); }
};

Figure* Figure::create(int id) {
    if (id == 1) return new Square;
    if (id == 2) return new Circle;
    return new Rectangle;
}

class User {
    Figure* fig;
public:
    User() {
        int input;
        cout << "Chon hinh (1-Vuong, 2-Tron, 3-HCN): ";
        cin >> input;
        fig = Figure::create(input);
    }
    ~User() { delete fig; }
    void action() {
        Figure* f = fig->clone();
        f->changeAttributes();
        delete f;
    }
};

int main() {
    User u;
    u.action();
    return 0;
}

Kết quả (ví dụ chọn 2)

Chon hinh (1-Vuong, 2-Tron, 3-HCN): 2
Circle created
Ban kinh: 3
Dien tich: 28.26