#include <iostream>
#include <string>
class Prototype {
public:
virtual ~Prototype() = default;
virtual Prototype* clone() const = 0;
virtual void print() const = 0;
};
class ConcretePrototype : public Prototype {
private:
int id;
std::string name;
int* data;
public:
ConcretePrototype(int _id, const std::string& _name, int value)
: id(_id), name(_name), data(new int(value)) {
std::cout << "Constructing ConcretePrototype [id=" << id << ", name=" << name
<< ", *data=" << *data << "]" << std::endl;
}
ConcretePrototype(const ConcretePrototype& other)
: id(other.id), name(other.name), data(new int(*(other.data))) {
std::cout << "Copy constructing ConcretePrototype (deep copy) [id=" << id
<< ", name=" << name << ", *data=" << *data << "]" << std::endl;
}
~ConcretePrototype() {
delete data;
std::cout << "Destructing ConcretePrototype [id=" << id << "]" << std::endl;
}
Prototype* clone() const override {
return new ConcretePrototype(*this);
}
void print() const override {
std::cout << " id: " << id << ", name: " << name
<< ", *data: " << *data << " (data address: " << data << ")" << std::endl;
}
void setData(int value) {
*data = value;
}
void setName(const std::string& newName) {
name = newName;
}
};
int main() {
std::cout << "=== Prototype Pattern Demo (Deep Copy) ===" << std::endl;
ConcretePrototype prototype(1, "Original", 100);
std::cout << "\n[Prototype object]:" << std::endl;
prototype.print();
ConcretePrototype* clone1 = dynamic_cast<ConcretePrototype*>(prototype.clone());
std::cout << "\n[Cloned object clone1] (initial state):" << std::endl;
clone1->print();
clone1->setData(200);
clone1->setName("Modified Clone");
std::cout << "\n[After modifying clone1]:" << std::endl;
std::cout << "Prototype object (should remain unchanged):" << std::endl;
prototype.print();
std::cout << "Cloned object clone1:" << std::endl;
clone1->print();
ConcretePrototype* clone2 = dynamic_cast<ConcretePrototype*>(prototype.clone());
std::cout << "\n[Cloned again to get clone2] (based on prototype):" << std::endl;
clone2->print();
clone2->setData(300);
clone2->setName("Another Clone");
std::cout << "\n[After modifying clone2]:" << std::endl;
std::cout << "clone1:" << std::endl;
clone1->print();
std::cout << "clone2:" << std::endl;
clone2->print();
delete clone1;
delete clone2;
std::cout << "\nProgram ended, all objects properly destructed." << std::endl;
return 0;
}