首页 > 编程语言 >C++深拷贝与浅拷贝

C++深拷贝与浅拷贝

时间:2023-04-25 18:44:59浏览次数:30  
标签:指向 int 堆区 内存空间 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;
}

标签:指向,int,堆区,内存空间,C++,拷贝,指针
From: https://www.cnblogs.com/ashes001/p/17353524.html

相关文章

  • Citrix XenDesktop 2203实现只允许图片从客户端拷贝至云桌面
    一、前言最近遇到个别客户需求,要求只允许从本地拷贝图片至云桌面,禁止其他文件、文字拷贝,禁止从VDA拷贝任何数据到客户端本地。二、实现步骤1、只允许图片从客户端拷贝到云桌面会话剪贴板写入允许的格式---需要设置CF_BITMAP(图片)客户端剪贴板重定向------需要开启限制会话剪贴板......
  • c++遍历搜索关键字
    #include<iostream>#include<windows.h>#include<string.h>#include<strsafe.h>#defineMAX_INPUT_LENGTH255usingnamespacestd;voidprintMemory(char*location,longsize){ printf("\n\n---------------------location......
  • 我总结的一些 C++ 高频面试题(收藏)
    extern“C”extern是C/C++语言中表明函数和全局变量作用范围的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。被extern"C"修饰的变量和函数是按照C语言方式编译和连接的。extern“C”这个声明的真实目的:解决名字匹配问题,实现C++与C的混合......
  • c++11 std::forward使用场景以及作用
    不使用 std::forward时,下述代码G不管传入什么类型的参数,只会最终调用 voidF(int&a);usingnamespacestd; voidF(int&a){  cout<<"int&version"<<a<<endl;} voidF(int&&a){  //dosomething  cout<<"in......
  • C++语言亚马逊国际获取AMAZON商品详情 API接口
    跨境电子商务是一种全新的互联网电商模式,运用电子化方式促成线上跨境交易,利用跨境物流运送商品,有利于打破传统的贸易格局,成为新的经济增长点。对我国来说,跨境电商平台正用一种全新的力量改变我国产业链的结构,并有利于增加贸易机会,拓展我国外贸在国际市场的广度与深度,赢得广阔的海......
  • 名字修饰约定: extern "C"、extern "C++" 和__stdcall、__cdecl相关的约定、__imp_前
    关于extern_C通常,在C语言的头文件中经常可以看到类似下面这种形式的代码#ifdef__cplusplusextern"C"{#endif/****somedeclarationorso*****/#ifdef__cplusplus}#endif/*endof__cplusplus*/那么,这种写法什么用呢?实际上,这是为了让CPP能够与C......
  • 《c++徒步》方法篇
    按值传递和按地址传递参考链接:https://blog.csdn.net/scrence/article/details/79835572参考链接:https://www.jb51.net/article/250343.htm1、按值传递#include<iostream>usingnamespacestd;voidchangeNumber(intx);intmain(void){ inta=10; cout<<"a="......
  • C++ shared_ptr 虚析构函数 特殊
    classa{public:~a(){cout<<"a"<<endl;}classb:publica{public:~b(){cout<<"b"<<endl;}voidmain(){shared_ptrA;{shared_ptrB(newb());//智能指针内部,uses引用值为1A=B;//智能指针内部,uses引用值为2,子类父类的智能指针可以一起计数}//离开作用......
  • 【面试宝典】C/C++ 基础
    一.语言基础 数组和指针的区别 数组指针概念是用于储存多个相同类型数据的集合。 数组名是首元素的地址特殊的变量,存放的是其它变量在内存中的地址。 指针名指向了内存的首地址赋值只能一个一个元素的赋值或拷贝同类型指针变量可以相互赋值存放方式连续......
  • Effective C++总结
    1.视C++为一个语言联邦c++是C、面向对象C++、泛型编程、以及stl的集合。2.尽量以const\enum\inline替换#define3.尽可能使用const4.确定对象使用前已经被初始化5.了解C++默认生成并调用哪些函数7.为多态基类声明virtual析构函数8.别让异常逃离析构函数9.绝不在构造和析构过程中调......