原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有对象来创建新对象,而不是通过实例化类来创建新对象。原型模式的核心在于对象的克隆操作,这可以是浅拷贝也可以是深拷贝,具体取决于实现方式和需求。
浅拷贝(Shallow Copy):
- 浅拷贝复制对象的所有字段值,但是对于引用类型(如对象、数组等),它只是复制了引用而不是引用的实际对象。
- 这意味着新对象和原对象共享相同的引用类型数据的实例,修改其中一个对象的引用类型数据会影响另一个对象。
- 在 Java 中,Object 类的 clone() 方法通常实现的是浅拷贝。
深拷贝(Deep Copy):
- 深拷贝不仅复制对象的所有字段值,对于引用类型字段,它会创建引用对象的一个全新的副本。
- 这意味着新对象和原对象完全独立,修改一个对象的数据不会影响另一个对象。
- 实现深拷贝通常需要手动处理每个引用类型字段,确保它们也被正确地复制。
在使用原型模式时,选择浅拷贝还是深拷贝取决于具体需求。如果对象的内部状态比较简单,只包含基本类型数据或不可变对象,浅拷贝可能就足够了。但如果对象内部包含复杂的层级关系或者可变对象,深拷贝可能更合适,以避免共享状态带来的潜在问题。
示例代码
在 C++ 中,原型模式的实现通常依赖于类的拷贝构造函数或通过实现自定义的克隆函数来实现对象的复制。C++ 的拷贝分为浅拷贝和深拷贝,类似于其他编程语言。
C++ 原型模式的浅拷贝实现
在浅拷贝中,类成员指针或引用的对象不会被复制,而是只复制指针或引用本身。
cpp
#include <iostream>
#include <cstring>
// Prototype 类,包含一个指向 char 数组的指针,演示浅拷贝
class Prototype {
public:
char* data;
Prototype(const char* str) {
data = new char[strlen(str) + 1];
strcpy(data, str);
}
// 浅拷贝构造函数
Prototype(const Prototype& other) {
data = other.data; // 只复制指针,浅拷贝
}
// 打印数据
void print() {
std::cout << "Data: " << data << std::endl;
}
// 析构函数
~Prototype() {
delete[] data;
}
};
int main() {
Prototype original("Hello World");
Prototype clone = original; // 使用拷贝构造函数,浅拷贝
std::cout << "Original: ";
original.print();
std::cout << "Clone: ";
clone.print();
return 0;
}
输出:
cpp
Original: Data: Hello World Clone: Data: Hello World
在这个例子中,clone 和 original 都指向同一个 data 内存地址,修改其中一个的 data 会影响另一个。
C++ 原型模式的深拷贝实现
为了避免浅拷贝的共享问题,深拷贝会为指针成员创建一个全新的内存副本。
cpp
#include <iostream>
#include <cstring>
// Prototype 类,包含一个指向 char 数组的指针,演示深拷贝
class Prototype {
public:
char* data;
Prototype(const char* str) {
data = new char[strlen(str) + 1];
strcpy(data, str);
}
// 深拷贝构造函数
Prototype(const Prototype& other) {
data = new char[strlen(other.data) + 1]; // 为数据分配新的内存
strcpy(data, other.data); // 复制数据内容
}
// 打印数据
void print() {
std::cout << "Data: " << data << std::endl;
}
// 析构函数
~Prototype() {
delete[] data;
}
};
int main() {
Prototype original("Hello World");
Prototype clone = original; // 使用拷贝构造函数,深拷贝
std::cout << "Original: ";
original.print();
std::cout << "Clone: ";
clone.print();
// 修改 clone 的数据
clone.data[0] = 'h';
std::cout << "\nAfter modification:" << std::endl;
std::cout << "Original: ";
original.print();
std::cout << "Clone: ";
clone.print();
return 0;
}
输出:
cpp
Original: Data: Hello World
Clone: Data: Hello World
After modification:
Original: Data: Hello World
Clone: Data: hello World
在这个深拷贝的例子中,original 和 clone 的 data 是独立的。当修改 clone 的 data 时,original 并未受到影响。
总结
- 浅拷贝:在浅拷贝中,指针成员只是复制地址,导致两个对象共享相同的内存。
- 深拷贝:深拷贝通过为指针成员分配新的内存并复制数据,确保每个对象有独立的内存空间。