文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。
笔记资料仅供学习交流使用,转载请标明出处,谢谢配合。
如果存在相关知识点的遗漏,可以在评论区留言,看到后将在第一时间更新。
作者:Aliven888
操作系统:Windows7 x64 旗舰版
pyth环境:Python 3.7
C++编译器:Visual Studio 2018
在 python 中实现对象的拷贝需要导入 copy 库(import copy),浅拷贝通过 copy(对象A) 函数实现,而深拷贝通过 deepcopy(对象A) 实现。
在 C++ 面向对象编程中,浅拷贝通过默认的构造函数实现;而深拷贝的话,就需要开发者通过自定义一个拷贝构造函数来实现。
只拷贝当前对象,并不会拷贝当前对象中的子对象。也就是说当前对象的浅拷贝对象内存是不共享的,但是其子对象内存是共享。
# 导入拷贝库(copy)
import copy
A = [1,[2,3]] # A 列表对象中包含一个子列表对象
B = copy.copy(A) # 浅拷贝A对象,产生对象B
B.append(5) # 操作B对象,添加一个元素值 5
B[1].append(4) # 操作B对象中子对象,添加一个元素值 4
# 打印两个列表
print(A)
print(B)
==================== 输出 ====================
[1, [2, 3, 4]] # 因为子对象内存共享,所以打印 A 对象中存在新增元素 4
[1, [2, 3, 4], 5] # 当前对象内存不共(是新拷贝的一份),所以 元素值 5 只出现在 B 对象中
#include "stdafx.h"
#include
using namespace std;
class ClassA
{
public:
ClassA(char *chName, int iAge)
{
int len = strlen(chName) + 1;
m_chName = new char[len];
strncpy_s(m_chName, len, chName, len);
m_iAge = iAge;
printf("Constructor .... [%s]\r\n", m_chName);
}
~ClassA()
{
printf("Destructor .... [%s]\r\n", m_chName);
delete []m_chName;
m_chName[0] = '\0';
}
public:
char *m_chName; //名字
int m_iAge; //年龄
};
int _tmain(int argc, _TCHAR* argv[])
{
ClassA A("Aliven", 18); //定义A对象
ClassA B = A; //拷贝A对象,产生对象B
system("pause");
return 0;
}
输出结果:
在对象释放时,析构函数被调用了两次,因为对象中的指针在第一次调用析构函数时就已被释放,所以第二次在释放就会导致程序崩掉(如下图示)。
所谓的深拷贝,就是指 当前对象以及当前对象中的子对象均拷贝一份,拷贝对象和原对象之间的全部内存都是不共享的(各自是独立的)。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 导入拷贝库(copy)
import copy
A = [1,[2,3]] # A 列表对象中包含一个子列表对象
B = copy.deepcopy(A) # 深拷贝A对象,产生对象B
B.append(5) # 操作B对象,添加一个元素值 5
B[1].append(4) # 操作B对象中子对象,添加一个元素值 4
# 打印两个列表
print(A)
print(B)
==================== 输出 ====================
[1, [2, 3]] # 因为所有对象内存均不共享,所以打印 A 对象数据元素不变化
[1, [2, 3, 4], 5] # 当前对象内存不共(是新拷贝的一份),所以 元素值 4,5 均只出现在 B 对象中
#include "stdafx.h"
#include
using namespace std;
class ClassA
{
public:
//构造函数
ClassA(char *chName, int iAge)
{
int len = strlen(chName) + 1;
m_chName = new char[len];
strncpy_s(m_chName, len, chName, len);
m_iAge = iAge;
printf("Constructor .... [%s]\r\n", m_chName);
}
//自定义拷贝构造函数
ClassA(ClassA &s)
{
int len = strlen(s.m_chName) + 1;
m_chName = new char[len];
strncpy_s(m_chName, len, s.m_chName, len);
m_iAge = s.m_iAge;
}
~ClassA()
{
printf("Destructor .... [%s]\r\n", m_chName);
delete []m_chName;
m_chName[0] = '\0';
}
public:
char *m_chName; //名字
int m_iAge; //年龄
};
int _tmain(int argc, _TCHAR* argv[])
{
ClassA A("Aliven", 18); //定义A对象
ClassA B = A; //拷贝A对象,产生对象B
system("pause");
return 0;
}
输出结果:
在对象释放时,析构函数被调用了两次,因为是深拷贝,所以A对象中的指针在第一次被析构函数释放后,B对象中的指针不受影响,也可以被其析构函数释放,而且不会报错(如下图示)。