智能指针

C++11 智能指针概述

假装没事ソ 提交于 2020-02-28 05:15:02
0.什么是智能指针? 智能指针是一种用来管理资源指针的特殊对象,对象中有一个成员变量用来保存动态创建的裸指针,通过重载operator->方法实现类似于裸指针的使用方式。 1.智能指针的作用是什么? 我们平时使用C++编写代码时,动态内存管理是我们时刻关注的重点。动态内存管理不好,容易出现下述三类问题: 1、野指针(空悬指针) 一些内存单元已经被释放,但是指向这些内存的指针还在使用,这些已经释放的内存有可能被系统重新分配给应用使用,此时再使用野指针,会造成无法预测的错误。 int *p = new int(10); delete p; // 释放后再次访问,无法预测结果 cout << *p << endl; 2、重复释放 程序试图释放已经被释放的资源,或者已经被重新分配的资源。 int *p = new int(10); delete p; // 重复释放,运行时报错 delete p; 3、内存泄露 不再使用的动态内存没有进行释放,便会造成内存泄露。如果程序多次存在内存泄露行为,会导致内存占用急剧增长,最终程序会因为无法申请到足够的空闲内存而异常退出。 void TestRelease() { int* p = new int(10); // 未释放p return; } 这三类问题严重影响程序的高可用性。但是像JAVA这样的语言不会存在这样的问题

C++ | 智能指针再探

≡放荡痞女 提交于 2020-02-27 02:55:40
上篇博客我们模拟实现了 auto_ptr 智能指针,可我们说 auto_ptr 是一种有缺陷的智能指针,并且在C++11中就已经被摈弃掉了。那么本章我们就来探索 boost库和C++11中的智能指针以及其实现方法。 文章目录: 一、独占型智能指针 scope_ptr 二、强 智能指针shared_ptr 三、弱 智能指针 weak_ptr 准:在本文中模拟的智能指针并不与库中的智能指针的实现完全相同,只是为了通过探究其实现原理而进行的一种模拟。 一、独占型智能指针 scope_ptr 在 boost中有一种 scope_ptr 指针,可以说这是boost库中最为简单的一种智能指针了。相对于前两种智能指针而言, scope_ptr 规定,一个智能指针只能引用一块堆内存,当这个指针的作用域消失之后自动释放。 scope_ptr 实现起来很简单,只需要将拷贝构造函数和赋值函数的接口屏蔽起来即可。 template < typename T > class Scope_ptr { public : Scope_ptr ( T * ptr ) { m_ptr = ptr ; } ~ Scope_ptr ( ) { delete m_ptr ; m_ptr = NULL ; } T & operator * ( ) { return * m_ptr ; } T * operator - > (

第六十一课、智能指针类模板

心不动则不痛 提交于 2020-02-25 02:04:18
一、智能指针 1、智能指针的意义 (1)、现代c++开发库中 最重要的类模板之一 (2)、c++中 自动内存管理 的重要手段 (3)、能够很大程度上 避开内存相关的 问题 2、STL中的只能指针 auto_ptr (1)、 生命周期结束时,销毁指向的内存空间 (2)、 不能指向堆数组 (否则发生内存泄漏),只能指向堆对象(变量) (3)、一片堆空间 只属于一个内存指针对象 (防止多次释放) (4)、多个只能指针对象 不能 指向同一片堆空间 #include <iostream> #include <string> #include <memory> using namespace std; class Test { string m_name; public: Test(const char* name) { cout << "Hello, " << name << "." << endl; m_name = name; } void print() { cout << "I'm " << m_name << "." << endl; } ~Test() { cout << "Goodbye, " << m_name << "." << endl; } }; int main() { auto_ptr<Test> pt(new Test("D.T.Software")); cout

boost智能指针小结

你说的曾经没有我的故事 提交于 2020-02-18 06:29:39
1.STL的指针auto_ptr当拷贝构造或者赋值时会发生控制权的转移,所以不能被当做元素存储到数组或者标准库的容器中去,当然也不能用指向数组的指针去初始化一个auto_pt对象。下面介绍几个此类的几个关键方法。 ap.reset(p); 如果p与ap的值不相同,则删除ap指向的对象并且将ap绑定到p。 ap.release(); 返回ap所保存的指针并且使ap成为未绑定的。 ap.get(); 返回ap所保存的指针。 2.boost::scoped_ptr/boost::scoped::array。 这两个只能指针不会存在所有权转移的问题,因为他们的拷贝构造函数和=操作符被声明为私有成员。。。重载了*和->操作符;还有一个reset()函数可以手动销毁指向的对象。 3.boost::shared_ptr/boost::shared_array。 该智能指针也重载了*和->操作符; reset()也是用于显式手动销毁对象的函数; use_count()用来检查当前指向所管理对象的shared_ptr的个数。 由于采用和引用计数机制来实现共享语意,所以可以存储到STL的容器中去,但是不可避免的出现了循环计数的问题。此问题用boost::weak_ptr来解决。boost::weak_ptr中存储的是指向一个已经由boost::shared_ptr所管理对象的弱引用

C++11 智能指针

安稳与你 提交于 2020-02-17 09:07:08
本文内容源自 C++11 智能指针 原作者:Babu_Abdulsalam 本文翻译自 CodeProject ,转载请注明出处。 引入 Ooops. 尽管有另外一篇文章说 C++11 里的智能指针了。近来,我听到许多人谈论 C++ 新标准,就是所谓的 C++0x/C++11。 我研究了一下 C++11 的一些语言特性,发现确实它确实有一些巨大的改变。我将重点关注 C++11 的智能指针部分。 背景 普通指针(normal/raw/naked pointers)有哪些问题? 让我们一个接一个的讨论。 如果不恰当处理指针就会带来许多问题,所以人们总是避免使用它。这也是许多新手程序员不喜欢指针的原因。指针总是会扯上很多问题,例如 指针所指向对象的生命周期 , 挂起引用 (dangling references)以及 内存泄露 。 如果一块内存被多个指针引用,但其中的一个指针释放且其余的指针并不知道,这样的情况下,就发生了挂起引用。 而内存泄露,就如你知道的一样, 当从堆中申请了内存后不释放回去,这时就会发生内存泄露 。有人说,我写了清晰并且带有错误验证的代码,为什么我还要使用智能指针呢?一个程序员也问我:“嗨,下面是我的代码,我从堆(heap)中申请了一块内存,使用完后,我又正确的把它归还给了堆,那么使用智能指针的必要在哪里?” void Foo ( ) { int * iPtr =

C++ 进阶 ----智能指针

瘦欲@ 提交于 2020-02-16 01:05:02
1基本概念 1.1指针的危害: 指针未初始化 野指针: 内存泄漏(申请动态内存 未释放) 1.2分类 1.3本质 将指针封装为 类对象成员 ,并在 析构函数 里删除指针指向的内存。 1.4不同 名称 不同 auto_ptr 马上删除。 unique_ptr 马上删除。 scoped_ptr 马上删除。 shared_ptr 计数为0删除。 weak_pt 不删除 2auto_ptr 2.1作用 对作用域内的动态分配对象的 自动释放 2.2基本类型 int * p = new int ( 10 ) ; cout << * p << endl ; //这样会导致内存泻露 通过valgrind ./a.out 就可以看出申请一个 释放0个 泄露4个字节 //智能指针 miniSTL :: auto_ptr < int > ap ( p ) ; cout << * ap << endl ; //ap等同与p 通过valgrind ./a.out 就可以看出申请一个 释放1个 无泄露 2.3类类型 Test * t = new Test ; t - > Func ( ) ; //通过valgrind ./a.out 就可以看出申请一个 释放0个 泄露1个字节 miniSTL :: auto_ptr < Test > apt ( t ) ; t - > Func ( ) ; /

智能指针(HasPtr)实现 .

旧巷老猫 提交于 2020-02-15 17:38:15
智能指针显然是C++吸引人的地方之一,必须掌握。看了《C++primer》,里面着重讲了智能指针的实现方式。 书中说到: “HasPtr(注:就是自定义的智能指针)在其它方面的行为与普通指针一致。具体而言,复制对象时,副本和原对象将指向同一基础对象。如果通过一个副本改变基础对象,则通过另一个对象访问的值也会改变。 新的HasPtr类需要一个析构函数来删除指针。但是,析构函数不能无条件的删除指针。” 条件就是引用计数。 如果该对象被两个指针所指,那么删除其中一个指针,并不会调用该指针的析构函数,因为此时还有另外一个指针指向该对象。看来,智能指针主要是预防不当的析构行为,防止出现悬垂指针。 如上图所示,HasPtr就是智能指针,U_Ptr为计数器,定义如下: [cpp] view plain copy print ? class U_Ptr { friend class HasPtr; int *ip; size_t use; U_Ptr( int *p) : ip(p), use(1) { cout << "U_ptr constructor called !" << endl; } ~U_Ptr() { delete ip; cout << "U_ptr distructor called !" << endl; } }; class U_Ptr { friend class

第9课 智能指针示例

隐身守侯 提交于 2020-02-15 05:28:57
1. 内存泄漏( 臭名昭著的Bug ) (1)动态申请堆空间,用完后不归还 (2)C++语言中没有垃圾回收的机制 (3)指针 无法控制 所指堆空间的生命周期 2. 当代C++软件平台中的智能指针 (1)指针生命周期结束时 主动释放堆空间 (2)一片堆空间最多 只能由一个指针标识 (3) 杜绝指针运算和指针比较 3. 智能指针的设计的方案 (1)通过 类模板 描述指针的行为:能够定义不同类型的指针对象。 (2)重载指针特征操作符( -> 和* ):利用对象模拟原生指针的行为。 (3)智能指针的 使用军规 :只能用来指向堆空间中的 单个对象(即不能指定一个数组对象的空间)或者变量 【编程实验】智能指针 //SmartPointer.h #ifndef _SMARTPOINTER_H_ #define _SMARTPOINTER_H_ namespace DTLib{ //智能指针 template<typename T> class SmartPointer { T* m_pointer; public: SmartPointer(T* p = NULL) { m_pointer = p; } SmartPointer(const SmartPointer<T>& obj) { m_pointer = obj.m_pointer; //所有权转移,使得同一时刻只能由一个指针指向堆空间

C++总结(四)

主宰稳场 提交于 2020-02-15 02:23:48
一、多态 1.多态的概念 多态:同一个事物,在不同场景下表现出的不同的状态 2.多态的分类 静态多态(早绑定,静态联编): 在编译期间,根据所传递的实参类型或者实例化的类型,来确定到底应该调用那个函数即:在编译期间确定了函数的行为—函数重载、模板 动态多态(晚绑定,动态联编):在程序运行时,确定具体应该调用那个函数 3.动态多态的实现条件-- -在继承的体系中 虚函数&重写:基类中必须包含有虚函数(被virtual修饰的成员函数),派生类必须要对基类的虚函数进行重写 关于虚函数调用:必须通过基类的指针或引用调用虚函数 体现:在程序运行时,基类的指针或引用指向那个子类的对象,就会调用那个子类的虚函数 4.重写 1.基类中的函数一定是虚函数 2.派生类虚函数必须与基类虚函数的原型一致:返回值类型 函数名字(参数列表) 例外: a、协变–基类虚函数返回值基类的指针或引用 派生类虚函数返回派生类的指针或引用基类虚函数和派生类虚函数的返回值类型可以不同 b、析构函数:如果将基类中析构函数设置成虚函数,派生类的析构函数提供,两个析构函数就可以构成重写;两个析构函数名字不同 3.基类虚函数可以和派生类虚函数的访问权限不一-样 4、为了让编译器在编译期间帮助用户检测是否重写成功,C+ +11提供非常有用的关键字 1、override:专门]让编译帮助用户检测派生类是否成功重写了基类的虚函数

智能指针(pointer like classes)

岁酱吖の 提交于 2020-02-14 08:39:46
为什么要有智能指针 C++的内存分为两种,栈和堆。栈中的内存使用之后不需要程序员去释放,会被自动释放。而在堆中分配的内存,是不能自动回收,需要程序员通过书写代码去回收。(malloc在堆中分配的内存由free来回收,New在堆中分配的内存由delete来回收。) 如何智能回收内存 借助RAII机制,RAII(Resource Acquisition Is Initialization),是C++采用的一种管理资源的方式。RAII是采用栈和依构造、析构函数的特性来管理资源。文字描述不够清晰,我们用代码来演示: void test ( ) { ClassA * pClassA = new ClassA ( ) ; . . . . delete pClassA ; } 上诉代码表面看上去并没有问题,但在实际使用时,会经常有问题。比如在delete之前,函数退出了,那么这里就会发生内存泄漏。 前面说了,智能指针是依托栈和构造、析构的机制。如果我们把指针封装成一个类,类的构造函数分配内存,析构函数中释放内存。 在函数的最初,使用这个类构造对象,构造完,这个指针对象就指向了一块堆内存,可以使用这块内存。但是,这个指针对象在函数中是局部变量,是存储在函数栈中的。当函数结束时,该函数栈中所有的局部变量都会被释放,所以刚才构造的指针对象就会被销毁。而销毁一个对象,就会自动调用它的析构函数