C++/Python 编程开发 —— 浅拷贝与深拷贝【含代码案列 + 图解】

文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。


笔记资料仅供学习交流使用,转载请标明出处,谢谢配合。
如果存在相关知识点的遗漏,可以在评论区留言,看到后将在第一时间更新。
作者:Aliven888

文章目录

    • 1、编译环境以及软件
    • 2、简述
    • 3、浅拷贝
      • 3.1、python 案例
      • 3.2、C++ 案列
    • 4、深拷贝
      • 4.1、python 案例
      • 4.2、C++ 案列

1、编译环境以及软件

操作系统:Windows7 x64 旗舰版
pyth环境:Python 3.7
C++编译器:Visual Studio 2018

2、简述

  在 python 中实现对象的拷贝需要导入 copy 库(import copy),浅拷贝通过 copy(对象A) 函数实现,而深拷贝通过 deepcopy(对象A) 实现。

  在 C++ 面向对象编程中,浅拷贝通过默认的构造函数实现;而深拷贝的话,就需要开发者通过自定义一个拷贝构造函数来实现。

3、浅拷贝

 只拷贝当前对象,并不会拷贝当前对象中的子对象。也就是说当前对象的浅拷贝对象内存是不共享的,但是其子对象内存是共享。

图解:
C++/Python 编程开发 —— 浅拷贝与深拷贝【含代码案列 + 图解】_第1张图片

3.1、python 案例

# 导入拷贝库(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 对象中

3.2、C++ 案列

#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;
}

输出结果:

 在对象释放时,析构函数被调用了两次,因为对象中的指针在第一次调用析构函数时就已被释放,所以第二次在释放就会导致程序崩掉(如下图示)。

C++/Python 编程开发 —— 浅拷贝与深拷贝【含代码案列 + 图解】_第2张图片

4、深拷贝

  所谓的深拷贝,就是指 当前对象以及当前对象中的子对象均拷贝一份,拷贝对象和原对象之间的全部内存都是不共享的(各自是独立的)。

图解:
C++/Python 编程开发 —— 浅拷贝与深拷贝【含代码案列 + 图解】_第3张图片

4.1、python 案例

#!/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 对象中


4.2、C++ 案列

#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对象中的指针不受影响,也可以被其析构函数释放,而且不会报错(如下图示)。

C++/Python 编程开发 —— 浅拷贝与深拷贝【含代码案列 + 图解】_第4张图片

你可能感兴趣的:(C/C++,Python,面向对象编程,c++,python,深拷贝,浅拷贝)