程序员进阶:结构体深拷贝 vs 浅拷贝
创作时间:
2025-01-21 19:19:54
作者:
@小白创作中心
程序员进阶:结构体深拷贝 vs 浅拷贝
在编程的世界里,深拷贝和浅拷贝是两个经常被提及但又容易混淆的概念。它们在对象的复制过程中扮演着重要角色,理解它们的区别对于编写高效且无bug的代码至关重要。本文将带你深入了解深拷贝和浅拷贝的原理、实现方式以及应用场景,让你在编程的道路上更进一步。
01
深拷贝与浅拷贝的概念
深拷贝
深拷贝(Deep Copy)是指在拷贝对象时,会创建一个新的独立的对象,并复制原对象中的所有成员变量的值。深拷贝后的对象和原对象是完全独立的,修改一个对象不会影响另一个对象。
浅拷贝
浅拷贝(Shallow Copy)是指在拷贝对象时,只是复制了对象中的成员变量的值的引用或指针。浅拷贝后的对象和原对象共享一份数据,修改一个对象可能会影响另一个对象。
02
实现方式
C++中的实现
在C++中,深拷贝和浅拷贝主要通过复制构造函数来实现。
- 深拷贝:通过自定义复制构造函数实现。在复制构造函数中,分配新的内存空间,并将原对象的值复制到新对象中。
class MyClass {
private:
int* data;
int size;
public:
// 构造函数
MyClass(int s) : size(s) {
data = new int[size];
}
// 复制构造函数,实现深拷贝
MyClass(const MyClass& other) : size(other.size) {
data = new int[size];
for (int i = 0; i < size; i++) {
data[i] = other.data[i];
}
}
};
- 浅拷贝:如果没有显式定义复制构造函数,C++会提供一个默认的复制构造函数,它执行的是浅拷贝。默认的复制构造函数将简单地将原对象的成员变量的值复制给新对象,导致新对象和原对象共享相同的数据。
class MyClass {
private:
int* data;
int size;
public:
// 构造函数
MyClass(int s) : size(s) {
data = new int[size];
}
// 默认复制构造函数,执行浅拷贝
// MyClass(const MyClass& other) = default;
};
C语言中的实现
在C语言中,深拷贝和浅拷贝需要手动编写代码来实现。
- 浅拷贝:通过简单地将一个结构体或数组的成员值赋值给另一个结构体或数组来实现。这将导致两个对象共享相同的内存数据。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char* name;
int age;
} Person;
int main() {
Person person1;
person1.name = malloc(sizeof(char) * 10);
strcpy(person1.name, "John");
person1.age = 25;
Person person2 = person1; // 浅拷贝
// 修改 person2 的值
person2.name = malloc(sizeof(char) * 10);
strcpy(person2.name, "Alice");
person2.age = 30;
// 输出 person1 和 person2 的值
printf("person1: name=%s, age=%d\n", person1.name, person1.age);
printf("person2: name=%s, age=%d\n", person2.name, person2.age);
// 释放内存
free(person1.name);
free(person2.name);
return 0;
}
- 深拷贝:需要手动进行内存分配和数据复制。对于包含指针类型成员变量的结构体或数组,需要为每个指针类型的成员变量分配独立的内存空间,并将原始对象指针指向的数据复制到新分配的内存中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char* name;
int age;
} Person;
// 深拷贝的函数
void deepCopyPerson(Person* dest, const Person* src) {
dest->name = malloc(sizeof(char) * (strlen(src->name) + 1));
strcpy(dest->name, src->name);
dest->age = src->age;
}
int main() {
Person person1;
person1.name = malloc(sizeof(char) * 10);
strcpy(person1.name, "John");
person1.age = 25;
Person person2;
deepCopyPerson(&person2, &person1); // 深拷贝
// 修改 person2 的值
free(person2.name);
person2.name = malloc(sizeof(char) * 10);
strcpy(person2.name, "Alice");
person2.age = 30;
// 输出 person1 和 person2 的值
printf("person1: name=%s, age=%d\n", person1.name, person1.age);
printf("person2: name=%s, age=%d\n", person2.name, person2.age);
// 释放内存
free(person1.name);
free(person2.name);
return 0;
}
03
使用场景
深拷贝的使用场景:当类中包含指针成员变量时,需要确保每个对象都拥有独立的内存空间,以避免潜在的指针悬挂和内存泄漏问题。深拷贝可以用于复制动态分配的内存、复制其他资源等情况。
浅拷贝的使用场景:当类中的成员变量是基本类型或没有指针成员变量时,浅拷贝可以提供更高效的拷贝操作,避免不必要的内存分配和复制开销。
04
代码示例
C++示例
#include <iostream>
class Person {
private:
char* name;
int age;
public:
Person(const char* n, int a) {
name = new char[strlen(n) + 1];
strcpy(name, n);
age = a;
}
// 浅拷贝构造函数
Person(const Person& other) {
name = other.name;
age = other.age;
}
// 深拷贝构造函数
Person(Person& other) {
name = new char[strlen(other.name) + 1];
strcpy(name, other.name);
age = other.age;
}
void setName(const char* n) {
delete[] name;
name = new char[strlen(n) + 1];
strcpy(name, n);
}
void print() {
std::cout << "Name: " << name << ", Age: " << age << std::endl;
}
};
int main() {
Person p1("John", 25);
Person p2 = p1; // 浅拷贝
Person p3(p1); // 深拷贝
p1.setName("Mike");
p1.print();
p2.print();
p3.print();
return 0;
}
C语言示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char* name;
int age;
} Person;
// 浅拷贝函数
void shallowCopy(Person* dest, const Person* src) {
dest->name = src->name;
dest->age = src->age;
}
// 深拷贝函数
void deepCopy(Person* dest, const Person* src) {
dest->name = malloc(strlen(src->name) + 1);
strcpy(dest->name, src->name);
dest->age = src->age;
}
int main() {
Person person1;
person1.name = malloc(10);
strcpy(person1.name, "John");
person1.age = 25;
Person person2;
shallowCopy(&person2, &person1); // 浅拷贝
Person person3;
deepCopy(&person3, &person1); // 深拷贝
// 修改 person1 的值
free(person1.name);
person1.name = malloc(10);
strcpy(person1.name, "Mike");
person1.age = 30;
// 输出 person1、person2 和 person3 的值
printf("person1: name=%s, age=%d\n", person1.name, person1.age);
printf("person2: name=%s, age=%d\n", person2.name, person2.age);
printf("person3: name=%s, age=%d\n", person3.name, person3.age);
// 释放内存
free(person1.name);
free(person2.name);
free(person3.name);
return 0;
}
05
总结
深拷贝和浅拷贝是编程中重要的概念,用于实现对象的拷贝操作。深拷贝通过复制构造函数在新对象中创建独立的数据拷贝,而浅拷贝只是复制引用或指针,导致多个对象共享相同的数据。在选择使用深拷贝或浅拷贝时,需要根据类的成员变量类型和拷贝需求进行权衡。深刻理解深拷贝和浅拷贝的概念和实现原理,有助于避免潜在的错误和内存管理问题,并提高程序的可靠性和性能。
热门推荐
幼儿舞蹈教学的目标及方法
阿托伐他汀钙片的功效与副作用全解析
感冒发烧多喝水,喝的是什么水?
心病还需“心药”治
飞机飞行的四大力量:升力、重力、推力与阻力
朱鹮是我的“新邻居”
驗出脂肪肝怎麼辦?醫師分享:做到這些事就能有效逆轉!

数字人怎么和观众互动
研究建议:午睡达到这个量,相当于大脑重启,进入最佳状态
生本教育理念下,这样培育小学生自主学习的习惯
如何正确区分夫妻共同债务和个人债务
八字命理中如何通过生辰八字分析一个人的性格特征
异常信息如何返回给前端
电梯定期维护与检查:确保乘客安全的重要措施
AI是“吃电狂魔”?能有多耗电?中国这个解法值得关注
游境成语故事课程设计
家庭旅游攻略:宝宝也能乐在其中的游玩地推荐
写作小白必备!告别开头难,这些技巧让你文思泉涌!
猕猴桃升糖指数高吗?专家解读其营养价值
如何选择和使用滤镜,提升照片与视频的美感与个性
物理学家:时间旅行有可能实现,但前提是……
一个专攻健脾补气血的名方!脾好了,气血足了
超管用!寒假培养孩子阅读习惯的6个“套路”
A股主要指数普遍下跌,食品饮料板块表现亮眼
手机处理器天梯图(2025年2月),极客湾/3DMark/安兔兔/GB6全收集
用巧克力“复刻”千年历史
从0到1!如何利用GPT创作高质量的儿童绘本故事?(附提示词)
无骨鸡爪:舌尖上的柔韧美味
情人节观察:为什么恋爱需要仪式感?
月收入5000在当今社会,到底算高收入还是低收入?你怎么看?