智能指针

C++11——智能指针

孤街浪徒 提交于 2019-11-29 00:22:57
1. 介绍    一般一个程序在内存中可以大体划分为三部分——静态内存(局部的static对象、类static数据成员以及所有定义在函数或者类之外的变量)、栈内存(保存和定义在函数或者类内部的变量)和动态内存(实质上这块内存池就是堆,通常通过new/malloc操作申请的内存)。对于静态内存和栈内存来说,编译器可以根据它们的定义去自动创建和销毁的相应的内存空间。而对于动态内存,由于程序只有在运行时才知道需要分配多少内存空间,所以只能由程序员去动态的去创建和回收这块内存。    而对于动态内存的回收是一个很复杂的问题,经常会因为一些难以观察的细节遗忘对一些对象的释放造成内存泄露,比如下面的代码: #include <iostream> #include <exception> using namespace std; class myException : public exception { public: const char* what_happened() const throw(){ return "error: what you have down is error."; } }; void check(int x){ if(x == 0){ throw myException(); } } int main(){ string* str = new string(

C++基础

假装没事ソ 提交于 2019-11-28 21:36:32
静态多态和动态多态优缺点 avl树与红黑树的效率 实际上红黑树的查找大约需要logN次比较, 并且查找不可能超过 2*logN 次比较. 插入和删除的时间要增加一个常数因子, 因为不得不在下行的路径上和插入点执行颜色变化和旋转. 平均起来, 一次插入大约需要一次旋转. 因此插入的时间复杂度还是O(logN), 但是比在普通的二叉搜索树中要慢 avl树查找的时间复杂度为O(logN), 因为树一定是平衡的. 但是, 由于插入或删除一个节点时需要扫描两趟树, 一次向下查找插入点, 一次向上平衡树 AVL树保持每个结点的左子树与右子树的高度差至多为1, 从而可以证明树的高度为O(log(n)). Insert操作与delete操作的复杂度均为log(n), 旋转操作可能会达到log(n)次 avl树不如红黑树效率高, 也不如红黑树常用 有了avl树为什么还需要红黑树 1、红黑树放弃了追求完全平衡, 追求大致平衡, 在与平衡二叉树的时间复杂度相差不大的情况下, 保证每次插入最多只需要三次旋转就能达到平衡, 实现起来也更为简单. 2、平衡二叉树追求绝对平衡, 条件比较苛刻, 实现起来比较麻烦, 每次插入新节点之后需要旋转的次数不能预知. avl树是为了解决二叉查找树退化为链表的情况, 而红黑树是为了解决平衡树在插入、删除等操作需要频繁调整的情况 总结 红黑树的查询性能略微逊色于AVL树

c++智能指针介绍_补充

耗尽温柔 提交于 2019-11-28 20:39:15
不明白我做错了什么,这几天老婆给我冷战了起来,也不给我开视频让我看娃了。。哎,心累!趁着今晚的一些空闲时间来对智能指针做个补充吧。 写完上篇“智能指针介绍”后,第二天上班途中时,突然一个疑问盘踞在心头,感觉上篇文章介绍的有些缺陷或者遗漏。 问题:当两个智能指针引用同一个heap obj,那么当一个智能指针跳出其scope时,另一个智能指针是怎么知道所引用的heap obj现在变成了1(use_count)? 如果引用计数是“智能指针类”内部的一个member var,那么其会随着该智能指针而消失,对吧?但是另一个智能指针所拥有的独立的引用计数(member var)不应该知道要减一才对啊! 抛出这个问题后,回顾下Android实现的智能指针: sp<XYZ> sp_obj = new XYZ(); 安卓中的智能指针所引用的类都有一个要求:XYZ必须从RefBase继承而来,引用计数在基类RefBase中实现。 因此XYZ类对象被多个sp_obj_x所引用时,因为各个sp_obj_x都能访问和修改XYZ类内部的同一个引用计数器,因此可以容易知道什么时候真正释放这个XYZ类对象(heap obj)。 答案介绍: 如果两个智能指针想知道彼此释放资源与否,那么这两个智能指针之间必须能够“互相通信”,因此内部的“引用计数”就不能被单个类共享! 如何让两个stack obj能够分享信息呢

智能指针

时间秒杀一切 提交于 2019-11-28 20:21:07
智能指针---shared_ptr 1、什么是智能指针   智能指针(smart pointer) 是个特殊的类模板,重载了“->”和“*”运算符,实现了C++的自动内存回收机制 > 智能指针通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数器跟踪有多少个对象的指针指向同一对象。 > 在C++11中有四种智能指针,auto_ptr,shared_ptr,unique_ptr和weak_ptr。其中auto_ptr有很多不足之处,在C++11中已经建议废弃使用。都是在memory头文件中声明的。 2、对象指针    对象指针是函数内的局部变量,每次new出对象,但是函数返回时没有delete,造成的后果就是对象指针指向的堆区在函数运行完成后没有得到释放,对象也没有销毁,所以我们在使用动态内存时会出现两种问题,一是忘记释放内存,造成内存泄漏,二是指针还在使用就被释放,就会产生非法访问。 3、为什么使用智能指针    为了更加安全的只用动态内存,引入了智能指针的概念。智能指针的行为类似普通指针,区别在于智能指针赋值自动释放所指向的对象,标准库提供的两种指针的区别在于管理底层指针的方法不同,shared_ptr允许多个指针指向同一个对象,unique_ptr则“独占”所指向的对象。标准库还定义了一种名为weak_ptr的伴随类

C++ 之 智能指针 知识点

末鹿安然 提交于 2019-11-28 20:05:05
我们知道除了静态内存和栈内存外,每个程序还有一个内存池,这部分内存被称为自由空间或者堆。程序用堆来存储动态分配的对象即那些在程序运行时分配的对象,当动态对象不再使用时,我们的代码必须显式的销毁它们。 在C++中,动态内存的管理是用一对运算符完成的:new和delete,new:在动态内存中为对象分配一块空间并返回一个指向该对象的指针,delete:指向一个动态独享的指针,销毁对象,并释放与之关联的内存。 动态内存管理经常会出现两种问题:一种是忘记释放内存,会造成内存泄漏;一种是尚有指针引用内存的情况下就释放了它,就会产生引用非法内存的指针。 为了更加容易(更加安全)的使用动态内存,引入了智能指针的概念。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。标准库提供的两种智能指针的区别在于管理底层指针的方法不同,shared_ptr允许多个指针指向同一个对象,unique_ptr则“独占”所指向的对象。标准库还定义了一种名为weak_ptr的伴随类,它是一种弱引用,指向shared_ptr所管理的对象,这三种智能指针都定义在memory头文件中。 为什么用: 为了更加容易,更加安全的使用动态内存 ,有了智能指针。 是什么:智能指针是一个 负责自动释放所指向的对象 的指针。 有四种:shared_ptr,unique_ptr,weak_ptr,scoped_ptr

c++智能指针介绍

天大地大妈咪最大 提交于 2019-11-28 13:54:23
C++11标准引入了boost库中的智能指针,给C++开发时的内存管理提供了极大的方便。接下来这篇文件介绍shared_ptr/weak_ptr内部实现原理及使用细节。 C++不像java有内存回收机制,每次程序员new出来的对象需要手动delete,流程复杂时可能会漏掉delete,导致内存泄漏。于是C++引入智能指针,可用于动态资源管理,资源即对象的管理策略。 C++中的shared_ptr/weak_ptr和Android的sp/wp功能类似,都为解决多线程编程中heap内存管理问题而产生的。当程序规模较小时,我们可以手动管理new分配出来的裸指针,什么时候delete释放我们自己手动控制。 但是,当程序规模变大时,并且该heap内存会在各个线程/模块中进行传递和互相引用,当各个模块退出时,谁去释放?由此引入了智能指针的概念。 其原理可以概况为,内部通过引用计数方式,指示 heap内存对象 的生存周期,而 智能指针变量 作为一个stack变量,利用栈区变量由操作系统维护(程序员无法控制)的特点进行管理。 实现细节: 这样的东东(我们姑且称其为一个“类”,就像int/char/string为程序语言的内建类,我们也可以定义自己的类来使用)需要有什么特点? 1.这个类内部需要有个指针,就是保护那个经常犯错的裸指针: heap内存对象指针 。 2.这个类能够代表所有类型的指针

深度探索智能指针(SmartPointer) 二 (收藏)

戏子无情 提交于 2019-11-28 03:09:35
主题索引: 一、剖析C++标准库智能指针(std::auto_ptr) 1.DoyouSmartPointer? 2.std::auto_ptr的设计原理 3.std::auto_ptr高级使用指南 4.你是否觉得std::auto_ptr还不够完美? 二、C++条件,寻找构造更强大的智能指针(SmartPointer)的 策略 1.支持引用记数的多种设计策略 2.支持处理多种资源 3.支持Subclassing 4.支持多线程条件下,线程安全的多种设计策略 5.其它多种特殊要求下,再构造 三、GenericProgramming基础技术和SmartPointer 1.回首处理资源中的Traits技术 2.回首多线程支持的设计 四、COM实现中,SmartPointer设计原理 五、著名C++库(标准和非标准)中的SmartPointer现状 --------------------------------------------------------------------- 二、C++条件,寻找构造更强大的智能指针(SmartPointer)的策略 1.支持引用记数的多种设计策略 你听说过COM和它著名的IUnknown接口吧? IUnknown是干什么的?我要告诉你,IUnknown接口三个函数签名中, 两个是用来管理对象(CoClassObject,组件类对象

深度探索智能指针(Smart Pointer) 一 (收藏)

不打扰是莪最后的温柔 提交于 2019-11-28 03:09:18
主题索引: 一、剖析C++标准库智能指针(std::auto_ptr) 1.Do you Smart Pointer? 2.std::auto_ptr的设计原理 3.std::auto_ptr高级使用指南 4.你是否觉得std::auto_ptr还不够完美? 二、C++条件,寻找构造更强大的智能指针(Smart Pointer)的 策略 1.支持引用记数的多种设计策略 2.支持处理多种资源 3.支持Subclassing 4.支持多线程条件下,线程安全的多种设计策略 5.其它多种特殊要求下,再构造 三、Generic Programming基础技术和Smart Pointer 1.回首处理资源中的Traits技术 2.回首多线程支持的设计 四、COM实现中,Smart Pointer设计原理 五、著名C++库(标准和非标准)中的Smart Pointer现状 --------------------------------------------------------------------- 一、剖析C++标准库智能指针(std::auto_ptr) 1.Do you Smart Pointer? Smart Pointer,中文名:智能指针, 舶来品? 不可否认,资源泄露(resource leak)曾经是C++程序的一大噩梦.垃圾回收 机制(Garbage

SMART POINTER(智能指针)

别来无恙 提交于 2019-11-28 03:08:51
智能指针(smart pointer): 智能指针是其实是一个对象A,它带有一个模针成员变量m_p.用该A管理m_p,通过这种管理机制,可以防止由于new而导致的内存泄漏. 智能指针对象在使用时像指针一样.同时也具有一般对象的所有特征.如果要注意以下几点: 1,对象之间的赋值:若有A=B,则在赋值时, 首先要松查是否为自身赋值.如果不是,则释放A对象成员指针的内存空间, 然后要将B中的成员指针赋值于A的成员指针, 接着将B中的成员指针置为空,这样可以避免多个指针同时指向一个内存空间而产生多次析构此内存空间的错误. 所以,重载的赋值函数一般如下: operator =(Test& source_object); 此处不能为const 对象的引用,这是因为要修改source_object 的成员指针为空. 2,对于copy constroctor也有与operator=类似的情况.只不过不要释放A成员指针的内存空间,. 3,关于member template的问题,它往往用于兼容模板对象之间的相互赋值,copy constroctor.我们可以将它看成是个模板类(一个类). 譬如:auto_ptr<B>,这就是一个类名称 另:VC7.0中,成员模板的定义和实现必须放在类的定义中. 注:member template不能为static 或virtual 4,智能指针中必须重载的几个运算符

共享智能指针shared_ptr的实现

微笑、不失礼 提交于 2019-11-28 01:23:20
shared_ptr是一个最像指针的“智能指针”,是boost.smart_ptr库中最有价值、最重要的组成部分,也是最有用的,Boost库的许多组件——甚至还包括其他一些领域的智能指针都使用了shared_ptr,所以它被毫无悬念地收入了C++11标准。 shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针0,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。 shared_ptr也可以安全地放到标准容器中,是在STL容器中存储指针的最标准解法。 实现原理 #include<iostream> #include<vld.h> using namespace std; //shared_ptr //#define TEST class sharend_base { public: sharend_base():use_count(1) { #ifdef TEST cout << "Create sharend_base object." << endl; #endif } virtual void dispose() = 0;//纯虚函数 virtual void destroy() { delete this; } void release() { if (