C++深拷贝与浅拷贝

浅拷贝的问题

默认提供的拷贝构造就是浅拷贝,如果拷贝的对象中含有成员指针变量指向堆区中的内存空间,那么就会出现两个对象中的成员指针变量指向同一块堆区空间,当方法执行结束后,对象就会被释放,调用析构函数(析构函数中存在释放在堆区开辟的内存空间),就会存在一块内存空间被多次释放的问题。

解决办法

自己写拷贝构造,让拷贝构造后的对象中的成员指针变量指向一块新的内存空间。
image
image

//
// Created by Administrator on 2023/4/25.
//
#include <iostream>
using namespace std;
// 深拷贝和浅拷贝
class Person {
public:
    int p_age;
    int *p_weight;

    Person() {
        cout << "无参构造" << endl;
    }

    Person(int age, int height) {
        p_age = age;
        p_weight = new int(height);
        cout << "有参构造" << endl;
    }

    // 析构函数 用于释放手动在堆区开辟的空间
    ~Person() {
        if (p_weight != NULL) {
            delete p_weight;
            // 防止野指针
            p_weight = NULL;
        }
        cout << "析构函数" << endl;
    }

    // 拷贝构造 不写让编译器生成
    // 防止 浅拷贝带来的问题 自己写拷贝构造 避免这个问题
    Person(const Person &p) {
        cout << "自己写的拷贝构造,避免浅拷贝的问题" << endl;
        p_age = p.p_age;
        // 这是浅拷贝
        // p_height = p.p_height; 自动生成的就是这样

        // 深拷贝 重新开一块空间 防止出现重复释放的问题
        p_weight = new int(*p.p_weight);
    }
};

void test() {
    Person p1(10, 120);
    cout << "年龄为: " << p1.p_age << ", 体重为: " << *p1.p_weight << endl;
    Person p2(p1);
    cout << "年龄为: " << p2.p_age << ", 体重为: " << *p2.p_weight << endl;
    // 会 先释放p2 在释放p1
    // 释放p2后析构函数会将 堆区中开辟的空间释放了 p1在此执行析构 在此操作那块内存就会报错
}

int main() {
    test();
    return 0;
}

原文链接:https://www.cnblogs.com/ashes001/p/17353524.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++深拷贝与浅拷贝 - Python技术站

(0)
上一篇 2023年4月25日
下一篇 2023年4月25日

相关文章

  • 前缀和

    前缀和 一、介绍 前缀,顾名思义就是一个东西前面的点缀…(bushi 其实打比方来说就是:假如有一字符串ABCD,那么他的前缀就是A、AB、ABC、ABCD这四个从新从第一个字母一次往后开始拼接的字符串。当然这是字符串。但前缀和一般应用于数组,对于给定的数组a=[1,2,3,4],他的前 i 项和sum[i]就表示数组中a[0]~a[i]的和,具体为:s…

    C++ 2023年5月3日
    00
  • 高效c语言1快速入门

    本章将开发你的第一个C语言程序:传统的 “Hello, world!”程序。然后讨论一些编辑器和编译器的选项,并阐述移植性问题。 Hello, world! #include <stdio.h> #include <stdlib.h> int main(void) { puts(“Hello, world!”); return EXI…

    C++ 2023年5月10日
    00
  • 第三部分:Spdlog 日志库的实现原理

    Spdlog 是一个快速、异步的 C++ 日志库,被广泛应用于 C++ 项目中。在这篇文章中,我们将探讨 Spdlog 日志库的实现原理。 Spdlog 的结构 Spdlog 由五个主要组件构成:Loggers、Sinks、Formatters、Async Logger 和 Registry。每个组件都扮演着不同的角色,共同协作记录并输出日志消息。 Logg…

    C++ 2023年4月18日
    00
  • 【Visual Leak Detector】核心源码剖析(VLD 1.0)

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇对 VLD 1.0 源码做内存泄漏检测的思路进行剖析。同系列文章目录可见 《内存泄漏检测工具》目录 目录 说明 1. 源码获取 2. 源码文件概览 3. 源码剖析 3.1 注册自定义 AllocHook 函数 3.2 存储调用堆栈信息 3.3 生成泄漏检测报告 4. 其他问题 4.1 如何区分…

    C++ 2023年4月27日
    00
  • 面试最常问的数组转树,树转数组 c++ web框架paozhu实现

    刚毕业同学,找工作常被问 二维数组转树,树转二维数组 需要支持无限层级实现,如果你了解这个语言那么实现起来还要一番思考 c++ web框架 paozhu使用 需要实现数据库表数据到前台菜单实现,就是这种功能 二维数组转树,树转二维数组 保存时候树二维数组,展示时候树树状。 这个技术难点在于无限递归,这个树程序基本原理 现在看看c++怎么实现的,无限递归,家肯…

    C++ 2023年4月25日
    00
  • C语言跳转浏览器打开指定URL

    #include <stdlib.h> int main() { // 定义要打开的URL char* url = “https://rjku.gitee.io/”; // 调用系统命令以默认浏览器打开URL char command[100]; sprintf(command, “open %s”, url); system(command);…

    C++ 2023年4月27日
    00
  • 【Visual Leak Detector】配置项 ReportTo

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇介绍 VLD 配置文件中配置项 ReportTo 的使用方法。同系列文章目录可见 《内存泄漏检测工具》目录 目录 说明 1. 配置文件使用说明 2. 设置报告输出的位置 2.1 测试代码 2.2 ReportTo = debugger 时的输出 2.3 ReportTo = file 时的输出…

    C++ 2023年4月18日
    00
  • C++的引用变量作为函数参数

    一、问题引入 在C++的中新增一个特性:按引用传递变量,虽然与按传递变量的地址可以实现相同的结果,但引用有其独特的地方。 引用传递: 引用经常被用作函数参数,使得函数中的变量名成为调用程序中的变量的别名。 通过引用变量用作参数,函数将使用原始数据,而不是其副本。 二、解决过程 举例说明: #include <iostream> using nam…

    C++ 2023年4月17日
    00
合作推广
合作推广
分享本页
返回顶部