这两个指针都指向同一个对象,因此在其中一个指针上调用 delete 语句会导致另一个指针也失效。为了避免这种情况,您应该确保在删除其中一个指针后,不再使用另一个指针访问该对象。如果您需要删除该对象,可以使用 delete[] 语句来删除数组中的对象,或者使用 delete 语句来删除单个对象。如果您需要保留对同一对象的访问,则应该创建一个指向该对象的新的指针,并使用 new 运算符来动态分配内存。
delete
delete[]
new
C++中this指针是一个指向当前对象的指针。在成员函数中,可以使用this指针来访问调用该函数的对象的成员变量和成员函数。...二、作为返回值的this指针 this指针可以作为返回值返回。这种情况下,返回的是指向调用该函数的对象的指针。为了实现这个功能,需要将返回类型设置为类的引用或指针类型。...函数内部,返回的是指向调用该函数的对象的指针。...这里使用了*this来访问调用该函数的对象。 三、作为函数参数的this指针 this指针也可以作为函数参数传递。这种情况下,可以在函数内部访问其他对象的成员变量和成员函数。...在getName函数内部,使用了this指针访问调用该函数的对象的成员变量name。
智能指针是行为类似于指针的类对象,但这种对象还有其他功能。使用指针指向一块新申请的内存的过程中,有时忘记释放新申请的内存,导致内存泄漏。为了防止该问题的发生,C++提供了智能指针模板类。...其思想就是将常规的指针变成一个类对象,该对象主要实现常规指针的功能,当该对象过期的时候,会自动调用其析构函数,在析构函数中完成内存释放的操作。...有关智能指针的注意事项 常规的指针在使用的过程中两个指针可能会指向同一个对象,这是不能接受的,因为程序在结束的时候会存在删除同一对象两次的问题,如下例: std::string* ps (new...在常规指针的基础上增加了所有权的概念,对于特定对象,只有一个指针可以拥有它,这样只有拥有对象的智能指针才能删除该对象。...如何选择合适的指针 程序要使用多个指向同一个对象的指针 使用shared_ptr。 程序不需要多个指向同一个对象的指针 使用unique_ptr。
对于普通的 局部变量(非静态局部变量),当离开它的作用域时,操作系统会自动将其释放。类对象在释放的时候是会自动调用该类的析构函数。...于是我们就想:如果是Test *t不是一个普通的指针变量,而是一个类对象的话,并且在类的析构函数中实现了释放动态内存的步骤,那么只要该指针变量一退出作用域时就会调用析构函数,达到了释放动态内存的目的。...可视作auto_ptr的替代品 持有对象的**独有权**,同一时刻只能有一个unique_ptr指向给定对象 shared_ptr 允许多个该智能指针**共享**堆中分配的内存(指向同一对象),通过*...先来看如下代码: auto_ptr px(new int(8)); auto_ptr py; py = px; 上述赋值语句将两个指针指向同一内存地址,在析构时可能会被两个对象各自...如果程序中不需要使用多个指向同一个对象的指针,则可使用unique_ptr 如果函数使用new分配内存,并返回指向该内存的指针,将其返回类型声明为unique_ptr是不错的选择。
多个指针指向同一个对象 ; 当最后一个智能指针销毁时 , 对象销毁 ; ② weak_ptr : 为了弥补 shared_ptr 的缺陷而引入的智能指针 ; ③ unique_ptr : 指向的对象所有权...互斥 , 同一时间 , 一个 对象 只能有一个 unique_ptr 智能指针 指向它 ; ④ auto_ptr ( 已弃用 ) : 该智能指针在 C++ 11 标准中 已弃用 , 但是为了向低版本兼容...: 该智能指针对象处于 栈内存中 // 智能指针释放 : 函数执行完毕后 , 就会调用智能指针对象的析构方法 // 判定引用计数 : 在智能指针对象析构方法的内部就会判定智能指针 操作对象 的引用计数...// 释放两个智能指针后 , student 对象的引用计数又变成了 0 // 两个智能指针会被回收 , 回收智能指针时 , 会做判定 , 当 对象的引用计数为 0 时 // 自动调用该对象的析构函数...: shared_ptr , 该智能指针内部实现了引用计数 , 多个共享智能指针指向同一个对象时 // 有 N 个 共享 智能指针同一个对象 , 其引用计数为 N return 0; } 运行结果
unique_ptr 是一个独享所有权的智能指针,它提供了严格意义上的所有权,包括: 1、拥有它指向的对象 2、无法进行复制构造,无法进行复制赋值操作。即无法使两个unique_ptr指向同一个对象。...(1)如果程序要使用多个指向同一个对象的指针,应选择shared_ptr。...这样的情况包括: 有一个指针数组,并使用一些辅助指针来标示特定的元素,如最大的元素和最小的元素; 两个对象包含都指向第三个对象的指针; STL容器包含指针。...智能指针的错误用法 1、使用智能指针托管的对象,尽量不要在再使用原生指针 很多开发同学(包括我在内)在最开始使用智能指针的时候,对同一个对象会混用智能指针和原生指针,导致程序异常。...std::shared_ptr e = std::make_shared(); 5、智能指针只能管理堆对象,不能管理栈上对象 栈上对象本身在出栈时就会被自动销毁,如果将其指针交给智能指针,会造成对象的二次销毁
即对指针name拷贝后会出现两个指针指向同一个内存空间。...两个对象的指针成员所指内存不同。...总结:浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。...再说几句: 当对象中存在指针成员时,除了在复制对象时需要考虑自定义拷贝构造函数,还应该考虑以下两种情形: 1.当函数的参数为对象时,实参传递给形参的实际上是实参的一个拷贝对象,系统自动通过拷贝构造函数实现...; 2.当函数的返回值为一个对象时,该对象实际上是函数内对象的一个拷贝,用于返回函数调用处。
和其他operator函数不同,这两个函数并没有重载new表达式或者delete表达式。实际上我们根本无法自定义new表达式或者delete表达式的行为。...当只传入一个指针类型的实参时,定位new表达式构造对象但是不分配内存,它允许我们在一个特定的、预先分配的内存地址上构造对象。...尽管定位new与allocator的construct非常相似,但是有一个重要的区别:我们传给construct的指针必须指向同一个allocator对象分配的空间,但是传给定位new的指针无须指向operator...将成员函数用作可调用对象 要想通过有一个指向成员函数的指针进行函数调用,必须首先利用.*或者->*运算符将该指针绑定到特定的对象上。...因此与普通的函数指针不同,成员指针不是一个可调用对象,这样的指针不支持函数调用运算符。 因为成员指针不是可调用对象,因此我们不能直接将一个指向成员函数的指针传递给算法。
,主要用到了这两点: 智能指针体现在把裸指针进行了面向对象的封装,在构造函数中初始化资源地址,在析构函数中负责释放资源 利用栈上的对象出作用域自动析构这个特点,在智能指针的析构函数中保证释放资源。...就好比SmartPtr* ptr = new SmartPtr();这段代码中,在堆空间定义一个智能指针,这依然需要我们手动进行delete,否则堆空间的对象无法释放,因为堆空间的对象无法利用出作用域自动调用析构函数...SmartPtr ptr1(new int); SmartPtr ptr2(ptr1); return 0; } 以上代码运行时,由于ptr2拷贝构造时默认是浅拷贝,两个对象底层的裸指针指向同一份资源...,对象析构时,会出现同一资源释放两次的错误(释放野指针),这里需要解决两个问题: 智能指针的浅拷贝 多个智能指针指向同一个资源的时候,怎么保证资源只释放一次,而不是每个智能指针都释放一次 不带引用计数的智能指针主要包括...在shared_ptr和weak_ptr的基类_Ptr_base中,有两个和引用计数相关的成员,_Ptr是指向内存资源的指针,_Rep是指向new出来的计数器对象的指针 class shared_ptr
C++的动态内存管理是通过new和delete两个操作来完成的,即用new来申请空间,用delete来释放空间。在使用new和delete时,注意以下原则。...从程序的输出可以看出,在将指针one所指向的空间释放后,为指针p申请的空间就是原来one所指向的空间。...由此可知,多次释放同一块内存空间,即使不导致程序运行中断,也会破坏环境,使指针与所对应的空间的隶属关系出现混乱,从而导致逻辑错误。在大型程序设计中,这种逻辑错误的查找会变得十分费时费力。...**注意:**当指针p的值为NULL时,多次使用delete p并不会带来麻烦,因为释放空指针的空间实际上不会导致任何操作。所以,将“不用”的指针设置为NULL是一个好的编程习惯。...当使用delete[]释放内存空间时,会逐个调用对象的析构函数并完成最终的内存空间的释放。使用delete释放对象数组时,则只会调用单个对象的析构函数,造成内存泄漏。
具体而言,复制对象时,副本和原对象都指向同一存储区域,如果通过一个副本改变其所指的值,则通过另一对象访问的值也会改变.所不同的是,智能指针能够对内存进行进行自动管理,避免出现悬垂指针等情况。...当有多个指针指向同一个基础对象时,如果某个指针delete了该基础对象,对这个指针来说它是明确了它所指的对象被释放掉了,所以它不会再对所指对象进行操作,但是对于剩下的其他指针来说呢?...智能指针将一个计数器与类指向的对象相关联,引用计数跟踪共有多少个类对象共享同一指针。...然后增加右操作数所指对象的引用计数(为何增加:因为此时做操作数指向对象即右操作数指向对象)。 析构函数:调用析构函数时,析构函数先使引用计数减1,如果减至0则delete对象。...如期,在离开大括号后,共享基础对象的指针从3->2->1->0变换,最后计数为0时,pa对象被delete,此时使用getX()已经获取不到原来的值。
从程序的输出可以看出,在将指针one所指向的空间释放后,为指针p申请的空间就是原来one所指向的空间。...由此可知,多次释放同一块内存空间,即使不导致程序运行中断,也会破坏环境,使指针与所对应的空间的隶属关系出现混乱,从而导致逻辑错误。在大型程序设计中,这种逻辑错误的查找会变得十分费时费力。...**注意:**当指针 p 的值为 NULL 时,多次使用 delete p 并不会带来麻烦,因为释放空指针的空间实际上不会导致任何操作。所以,将“不用”的指针设置为 NULL 是一个好的编程习惯。...,delete[] 调用了三次析构函数,完成了对象数组的释放。...当使用delete[]释放内存空间时,会逐个调用对象的析构函数并完成最终的内存空间的释放。使用 delete 释放对象数组时,则只会调用单个对象的析构函数,造成内存泄漏。
42); // p指向的对象只有p一个引用者 auto q(p); // p和q指向同一对象,此对象有两个引用者 每个shared_ptr都有一个与之关联的引用计数器reference count,...delete内存:这种情况下内存再也不可能归还给自由空间,也就是我们所说的“内存泄漏”问题 使用已经释放掉的对象:通过在释放内存后将指针置为空,有时可以检测出这种问题 同一块内存释放两次:当有两个指针指向相同的动态分配对象时可能发生这种错误...然而可能有多个指针指向同一块内存: int *p(new int(42)); // p指向动态内存 auto p = q; // p和q指向同一块内存 delete p; // p和q均变得无效 p...: unique_ptr u1:空unique_ptr,可以指向类型为T的对象,u1会调用delete来释放指针 unique_ptr u2:同上,但是会调用D的可调用对象来释放它的指针...如果我们在delete一个指向数组的指针时忽略了方括号,或者在delete一个指向单一对象的指针时使用了方括号,其行为是未定义的。 3.
智能指针 在C++库中最重要的类模板之一 智能指针实际上是将指针封装在一个类里,通过对象来管理指针....; //打印数值1 一片堆空间只属于一个智能指针对象(因为多个指向相同地址的智能指针调用析构函数时,会出现bug) 当auto_ptr被拷贝或赋值后,则自身的指针指向的地址会被抢占...可以发现在调用p1=p2时, 首先会delete p1对象的类成员指针(调用~Test(1)析构函数),然后将p2对象的类成员指针赋值给p1(p1=0x8db1018), 最后修改p2指针地址为NULL...STL中的智能指针shared_ptr(需要C++11支持) 带有引用计数机制,支持多个指针对象指向同一片内存(实现共享) 提供swap()成员函数,用来交换两个相同类型的对象,比如: shared_ptr...,该模板类析构时,不会自动摧毁所指向的对象(需要手工delete) -QSharedPointer 头文件 带有引用计数机制,支持多个指针对象指向同一片内存(实现共享)
这就是为什么调用delete mptr;来删除指向的对象 需要注意的是,这段代码并不会调用指向的对象的析构函数。析构函数是在delete mptr;这一行被调用时自动调用的。...事实上,当你在主线程中使用delete删除对象p时,它会释放该对象所占用的内存。但是,这并不意味着该内存立即被操作系统回收或被其他程序使用。...比如我用智能指针托管数组的话,那delete就不行,得用delete[] 再比如我让它管理的不是内存资源,而是文件资源,那释放文件也绝对不可能用delete释放的 所以在我们除了智能指针在堆内存外,怎么正确指导智能指针来正确删除呢...先讲讲智能指针内部是咋回事吧 unique_ptr shared_ptr 一个不带计数,一个带计数 他们两个都是可以带自定义删除器的 看他们的源码 ~unique_ptr(){ 是一个函数对象的调用...这个 lambda 表达式接受一个 int 指针作为参数,并在其函数体中使用 delete[] 运算符来释放该指针所指向的数组 当 ptr1 被销毁时,它会调用这个 lambda 表达式来释放其所指向的数组
简单的说,shared_ptr实现包含了两个部分:(1)一个指向堆上创建的对象的裸指针 raw_ptr。(2)一个指向内部隐藏的、共享的管理对象 shared_count_object。...其中use_count是当前这个堆上对象被多少对象引用了,简单来说就是引用计数。2.1、shared_ptr内存模型shared_ptr内部包含两个指针,一个指向对象,一个指向控制块。...reset()带参数时,若智能指针s是唯一指向该对象的指针,则释放并指向新的对象。若智能指针s不是唯一指向该对象的指针,则引用计数减一,并指向新的对象。...)构造了两个智能指针sp1和sp2,而他们之间是没有任何关系的,在离开作用域之后this将会被构造的两个智能指针各自析构,导致重复析构的错误。...2,在离开作用域之后,ap和bp的引用计数减为1,并不回减为0,导致两个指针都不会被析构,产生内存泄漏。
1.智能指针的由来 C++中,动态内存的管理是通过一对运算符来完成的,new用于申请内存空间,调用对象构造函数初始化对象并返回指向该对象的指针。...delete接收一个动态对象的指针,调用对象的析构函数销毁对象,释放与之关联的内存空间。...总的来说,使用引用计数有如下两个目的: (1)节省内存,提高程序运行效率。如何很多对象拥有相同的数据实体,存储多个数据实体会造成内存空间浪费,所以最好做法是让多个对象共享同一个数据实体。...辅助类将引用计数与智能指针类指向的对象封装在一起,引用计数记录有多少个智能指针指向同一对象。...4.智能指针的实现模板 智能指针管理对象,本质上是以栈对象来管理堆对象,在《Effective C++》的条款13中称之为资源获取即初始化(RAII,Resource Acquisition Is Initialization
假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数。...多态 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。简单的说:就是用基类的指针或引用指向子类的对象。...C++的多态性具体体现在运行和编译两个方面: (1)在程序运行时的多态性通过继承和虚函数来体现; (2)在程序编译时多态性体现在函数和运算符的重载上; 虚函数 使用virtual关键字声明的是虚函数...就是基类的指针或引用有可能指向不同的派生类对象,对于非虚函数,执行时实际调用该函数的对象类型即为该指针或引用的静态类型(基类类型);而对于虚函数,执行时实际调用该函数的对象类型为该指针或引用所指对象的实际类型...;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已,引用变量内存单元保存的是被引用变量的地址。
1.什么是多态 在C++中,多态(Polymorphism)是指通过基类指针或引用来访问派生类对象的一种机制。简单来说,它允许我们在基类类型的指针或引用上调用派生类对象的成员函数。...通过使用基类指针或引用指向派生类对象,并调用该虚函数,实际上在运行时会根据对象的实际类型调用合适的函数。...: 通过使用基类引用p指向派生类对象,并调用虚函数BuyTicket(),实际上在运行时会根据对象的实际类型调用合适的函数来实现多态,也就是不同的对象完成同一个行为会有不同的状态——普通人买票全价,学生买票半价...只有派生类Student的析构函数重写了Person的析构函数,delete对象调用析构函数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。...结果如下: 这里要注意派生类的析构调用完之后会自动调用基类对象的析构函数,所以这里基类的析构函数调用了两次 我们可以对比一下,当没有实现多态时,对于delete对象调用析构函数是不会根据所指向的对象调用相应的析构函数
这是一个好的实践,但在没有拷贝构造函数的情况下,如果多个对象指向同一块内存,析构函数会尝试释放相同的内存多次,导致程序崩溃。...这样,当 **s1** 和 **s2** 的析构函数被调用时,会尝试释放同一块内存,导致程序崩溃。...** 详细分析 通过以上代码及解析可以发现,在VS下,当没有拷贝构造函数的话,会直接将被构造的那个对象中成员的指针指向拿来构造的对象的指针指向的空间。...当程序结束时,因为有析构函数,所以会将两个对象进行析构,又因为两个对象中的指针指向的是同一块空间,所以会对同一块空间析构两次,造成程序崩溃。..._str指向原对象的字符串数据_str,新对象的引用计数指针_count也指向原对象的引用计数。
领取专属 10元无门槛券
手把手带您无忧上云