设计模式之原型模式
题目
[实验任务一]:向量的原型
用C++完成数学中向量的封装,其中,用指针和动态申请支持向量长度的改变,使用浅克隆和深克隆复制向量类,比较这两种克隆方式的异同。
类图
Java
MyVector
package com.gazikel;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class MyVector implements Cloneable, Serializable {
private int size;
private final int max_size = 5;
private List<Integer> value = null;
public MyVector() {
size = max_size;
value = new ArrayList<>();
}
public MyVector(int size, int...args) {
this.size= size;
value = new ArrayList<>();
for (int i = 0; i < size; i++) {
value.add(args[i]);
}
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public List<Integer> getValue() {
return value;
}
public void setValue(Integer value) {
this.value.add(value);
}
public void print() {
for (Integer integer : value) {
System.out.print(integer + "\t");
}
System.out.println("");
}
// 实现加减乘除的运算
public Object deepClone() {
// 创建流对象
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
// 序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
// 当前这个对象以对象流的方式输出
oos.writeObject(this);
// 反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
MyVector myVector = (MyVector) ois.readObject();
return myVector;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Client
package com.gazikel;
import java.util.Vector;
public class Client {
public static void main(String[] args) {
MyVector vector = new MyVector(5, 10, 5, 6, 2, 1);
MyVector vector_clone = (MyVector) vector.deepClone();
System.out.println(vector.getValue().hashCode());
System.out.println(vector_clone.getValue().hashCode());
vector.print();
vector_clone.print();
}
}
C++
main.cpp
#include<iostream>
using namespace std;
// 维数上限
const int MAXDIMENSION = 100;
const int max_count = 50;
class Vector{
private:
double *value;
int max_count;
int count;
public:
Vector() {
value = new double[max_count + 1];
count = 50;
for (int i = 0; i < count; i++) {
value[i] = i;
}
}
Vector(int size) {
value = new double[size + 1];
count = size;
for (int i = 0; i < size; i++) {
value[i] = i;
}
}
Vector(const Vector &v) {
value = new double[v.count + 1];
memcpy(value, v.value, count);
}
~Vector() {
delete[] value;
}
int size()
{
return count;
}
void reserve(int new_max_count)
{
double *temp = new double[count];
memcpy(temp, value, count * sizeof(double));
delete[] value;
max_count = new_max_count;
value = new double[max_count + 1];
value = temp;
value[count] = '\0';
}
void resize(int new_count)
{
if (new_count < count)
{
for (int i = new_count; i < count; i++)
{
value[i] = '\0';
}
}
if (count <= new_count && new_count <= max_count)
{
for (int i = count; i < new_count; ++i)
{
value[i] = rand();
}
}
if (new_count > max_count)
{
max_count = 2 * max_count;
reserve(max_count);
for (int i = count; i < new_count; i++)
{
value[i] = rand();
}
}
count = new_count;
}
void push_back(double d)
{
if (count < max_count)
{
value[count] = d;
}
else
{
max_count = max_count * 2;
double *temp = new double[max_count];
memcpy(temp, value, count * sizeof(double));
delete[] value;
value = temp;
value[count] = d;
}
++count;
}
bool operator == (const Vector& object1)
{
int count1;
count1 = object1.count;
if (count == count1)
{
for (int i = 0; i < count1; i++)
{
if (value[i] != object1.value[i])
return false;
}
return true;
}
else
return false;
}
//重载赋值操作符
void operator = (const Vector& right_side_object)
{
max_count = right_side_object.max_count;
count = right_side_object.count;
//先将右侧对象拷贝到临时对象中,然后再销毁左侧对象
double *temp = new double[max_count + 1];
memcpy(temp, right_side_object.value, count * sizeof(double));
delete[] value;
value = temp;
}
Vector* clone() {
Vector* newVector = new Vector;
*newVector = *this;
return newVector;
}
void print() {
for (int i = 0; i < count; i++) {
cout << value[i] << " ";
}
cout << endl;
}
};
int main(void) {
Vector* v1 = new Vector(5);
cout << v1;
v1->print();
Vector* v2 = v1->clone();
cout << v2;
v2->print();
}
浅拷贝与深拷贝
浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
2020-11-24 double类型运算异常