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

C++之浅拷贝和深拷贝

时间:2023-06-05 11:44:59浏览次数:34  
标签:PtrAge int age C++ height Person 拷贝

浅拷贝:简单的复制拷贝操作

P1的生命周期结束后,判断m_PtrAge是否为空,很明显m_PtrAge的值是0x0100,不为空,释放m_PtrAge指向的内存;
P2的生命周期结束后,同样判断m_PtrAge是否为空,很明显m_PtrAge的值也是0x0100,也不为空,再次释放m_PtrAge指向的内存空间;
两次释放都指向同一块内存空间,造成堆区的数据重复释放,固有以上的crash信息,这就是浅拷贝带来的风险。
解决办法:
利用深拷贝解决浅拷贝带来的风险,即让P2对象中的m_PtrAge指向另一个内存单元,这样2个对象调用析构函数后,各自释放自己的内存单元
深拷贝:在堆区重新申请内存空间,进行拷贝操作

#include<iostream>
#include<string.h>
#include<memory>
#include<stdio.h>
using namespace std;

//深浅拷贝操作
class Person
{
    public:
        
        Person()
        {
            printf("Person的构造函数调用\n");
        }

        Person(int a, int h)
        {
            m_age = a;
            m_height = new int(h);
            printf("Person的有参构造函数调用\n");
        }

        ~Person()
        {
            //将堆区开辟的空间释放掉
            if (m_Height != NULL)
            {
                delete m_Height;
                m_Height = NULL; //防止野指针出现
            }
            printf("Person的析构造函数调用\n");
        }

        Person(const Person &p)
        {
            printf("Person拷贝造函数调用\n");
            m_age = p.m_age; 
            // m_height = p.m_height; //编译器默认实现就是这行代码(浅拷贝)
            m_height = new int(*p.m_height); //深拷贝操作
        }
    int m_age;
    int *m_height;
}
int main()
{
  Person p1(18, 160);
  printf("Person p1.age: %d, *p1.height: %d\n", p1.age, *p1.height);
  Person p2(p1);
  printf("Person p2.age: %d, *p2.height: %d\n", p2.age, *p2.height);
  return 0;
}

 

标签:PtrAge,int,age,C++,height,Person,拷贝
From: https://www.cnblogs.com/lyfily-p-7439305/p/17457392.html

相关文章

  • C++智能指针:weak_ptr
    weak_ptr虽然是智能指针,但实际上是作为shared_ptr的辅助指针使用。weak_ptr通常不单独使用,一般用于查看对应的shared_ptr的信息。weak_ptr没有重载*,->等指针运算符。weak_ptr对象不会影响shared_ptr对象的引用计数。 #include<iostream>#include<string.h>#include<memory......
  • 故事会【深拷贝和浅拷贝】
    从前,有一个繁忙的城市。在这个城市里,有两个非常要好的朋友,小明和小红。他们分别经营着自己的商店,小明的商店卖的是水果,小红的商店卖的是鲜花。一天,小红发现她的鲜花生意非常好,但是她的鲜花不够卖。于是她想到了小明,她认为如果小明的水果店能帮她进货,那么她就能满足更多顾客的需求......
  • C++继承
      三类继承方式子类会将父类的所有非静态成员属性继承过来,只不过编译器隐藏了父类的私有属性,子类不可以访问。 1classBase{2public:3inta_;4protected:5intb_;6private:7intc_;8};910classSon:publicBase{11pu......
  • 一个基于C++11的异步安全日志库
    0源码获取gitee1概述这是一个基于c++11的异步日志库目前仅支持windows已通过VS2019+windows11测试。支持自动清理距今指定天数的日志支持设定日志文件输出路径2待实现支持linux3一个范例使用范例 std::unique_ptr<oct_tk::AsyncLogging>async_log=s......
  • C++ 多态原理
    多态就是多种形态,C++的多态分为静态多态与动态多态。动态多态就是通过继承重写基类的虚函数实现的多态,在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。多态的总结:(1)用virtual关键字声明的函数叫做虚函数,虚函数肯定是类的......
  • QT的特殊命名空间方式和C++对比
    Qt有以下的写法QT_BEGIN_NAMESPACEnamespaceUi{classWidget;}QT_END_NAMESPACE在开始和结束关键字中间进行命名空间的创建及其内部类的声明 而C++则是直接进行创建namespaceMyNamespace{//在MyNamespace命名空间内定义的类、函数、变量等classMyC......
  • C++ 多态 虚函数virtual
    先解释虚函数,对于基类,子类继承基类后可能会调用其某个函数FA,而不同的子类继承了同一个基类后需要基类内某个同样的函数FA但又不是同个作用,此时则会在对应的子类内对应重载派生出FA_B函数和FA_C函数,而这时要求FA为虚函数(virtual)那为什么不各自写成一个函数B和C呢?这就是多态的意......
  • C++程序开发技巧
    引言类(class)的使用分为两种——基于对象(objectBased)和面向对象(objectoriented)基于对象是指,程序设计中单一的类,和其他类没有任何关系单一的类又分为:不带指针的类(classwithoutpointermembers)和带指针的类(classwithpointermembers)面向对象则是类(class)中涉及了类之间的关......
  • Effective Modern C++(四)再探移动语义与完美转发
    移动语义移动语义是c++11最为重要的特性之一,但这不代表着我们可以在任何时候都无脑地使用它。在以下几个情况下,移动语义并没有什么用处。没有移动操作:要移动的对象没有提供移动操作,所以移动的写法也会变成复制操作。比如对于STL库中的array容器而言,他的元素都直接存储在了......
  • QT--C++简学
    2.1C++语言的新特点(对于C语言来说) 赋值:直接------- intx(100) 在定义的时候就可以赋值,相当于x=100;2.2输入(cin)--------输出(cout)  2.2.1   cout<<x<<endl;  //一个变量             --------printf     cout<<x<......