智能指针

C++之智能指针

被刻印的时光 ゝ 提交于 2021-02-14 17:44:53
我们都知道,C和C++常被人诟病的一点就是程序员需要自己来维护对动态内存的申请和释放,具体来说就是malloc/free和new/delete的成对出现。能够保证它们成对出现,是一个良好的编程习惯,但是即使做到这一点,就能够保证万无一失吗?我们看一个例子: 我们先定义一个简单的类A: class A { public: int a; inline void print(){cout << a << endl;} }; A * ptr = new A; ... delete ptr; 正常情况下,这段代码顺利执行则不会出现问题。但是当在执行delete操作之前如果程序抛出异常呢?这样就会导致delete不能够执行,进而导致内存泄露。解决办法很多,比如使用异常来控制,但是这样就会显得逻辑混乱,而且不够优美。这里我们介绍下智能指针(smart pointer)。 C++中包含众多的智能指针,比如STL中的auto_ptr,boost库中的shared_ptr,weak_ptr,scoped_ptr,intrusive_ptr等。我们一一介绍。 1.智能指针之 auto_ptr auto_ptr是包含在标准库中,只需要#include <memory>头文件即可。我们先看下auto_ptr的用法: auto_ptr<A> ptr(new A); ptr->print(); 可以看出

智能指针与句柄类(二)

心已入冬 提交于 2020-03-30 16:44:12
   之前文章 提到写时复制(copy-on-write)技术,要实现这种功能,针对上文中Handle代码,需要将size_t * use这个抽象出来,封装成一个引用计数类,提供写时复制功能。CUseCount类实现如下: 1 class CUseCount 2 { 3 public: 4 CUseCount(); 5 CUseCount(const CUseCount&); 6 ~CUseCount(); 7 8 bool only()const; //判断引用计数是否为0, 句柄类无法访问private int*p, 故提供此函数 9 bool reattach(const CUseCount&); //对计数器的操作, 用来代替 operator = 10 11 bool makeonly(); //写时复制, 表示是否需要赋值对象本身 12 13 private: 14 CUseCount& operator=(const CUseCount&); //提供reattach函数代替 operator = 15 int *p; //实现计数 16 }; 17 18 CUseCount::CUseCount():p(new int(1)) 19 {} 20 21 CUseCount::CUseCount(const CUseCount& u):p(u.p) 22 { 23 ++

C++的智能指针(shared_ptr,weak_ptr)

ぐ巨炮叔叔 提交于 2020-03-21 19:04:07
一:概述 参考资料:《C++ Primer中文版 第五版》 我们知道除了静态内存和栈内存外,每个程序还有一个内存池,这部分内存被称为自由空间或者堆。程序用堆来存储动态分配的对象即那些在程序运行时分配的对象,当动态对象不再使用时,我们的代码必须显式的销毁它们。 在C++中,动态内存的管理是用一对运算符完成的:new和delete,new:在动态内存中为对象分配一块空间并返回一个指向该对象的指针,delete:指向一个动态独享的指针,销毁对象,并释放与之关联的内存。 动态内存管理经常会出现两种问题:一种是忘记释放内存,会造成内存泄漏;一种是尚有指针引用内存的情况下就释放了它,就会产生引用非法内存的指针。 为了更加容易(更加安全)的使用动态内存,引入了智能指针的概念。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。标准库提供的两种智能指针的区别在于管理底层指针的方法不同, shared_ptr 允许多个指针指向同一个对象。属于强引用类型,他会维护引用计数的信息,即会记录当前有多少个存活的 shared_ptrs 正持有该对象. 共享的对象会在最后一个强引用离开的时候销毁( 也可能释放). unique_ptr 则“独占”所指向的对象。 标准库还定义了一种名为 weak_ptr 的伴随类,它是一种弱引用,指向shared_ptr所管理的对象,他不控制对象生命周期,

智能指针之unique_ptr

半城伤御伤魂 提交于 2020-03-21 12:53:36
概述 与shared_ptr不同,某个时刻只能有一个unique_ptr指向一个给定对象。当unique_ptr被销毁时,它所指向的对象也被销毁。同时,unique_ptr也没有类似于make_shared的标准库函数,当我们定义一个unique_ptr时,需要将其绑定到一个new返回的指针。因此初始化unique_ptr需要使用 直接初始化 的形式。例如: unique_ptr<double> p(new double(3.14)); // p指向一个值为3.14的double 并且,由于一个unique_ptr“拥有”(唯一指向)其指向的对象,所以unique_ptr不支持拷贝或者赋值操作: unique_ptr<string> p1(new string("southernEast")); unique_ptr<string> p2(p1); // 错误:不能拷贝 unique_ptr<string> p3; p3 = p2; // 错误:不能赋值 虽然我们不能拷贝或者赋值一个unique_ptr,但是我们能够通过使用release或reset函数来将一个非const的unique_ptr的指针所有权转移给另一个unique_ptr。例如: unique_ptr<string> p2(p1.realease()); // 将p1的指针所有权转移给p2,release将p1置空

智能指针实例

佐手、 提交于 2020-03-19 12:58:25
摘要: 智能指针:通过C++模板技术实现的一个类模拟指针的行为(如->、*) 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 >

第九课 智能指针

爷,独闯天下 提交于 2020-03-15 10:19:40
  智能指针在开发中无处不在,智能指针就是用C++模板技术实现的一个类。 智能指针历史:为了解决内存泄漏 使用智能指针: 智能指针的设计方案: 通过类模板描述指针的行为   能够定义不同类型的指针对象 重载指针特征操作符(->和*)   利用对象模拟原生指针的行为 对象在生命周期结束的时候会调用析构函数,然后在析构函数中主动的释放堆空间 C++原生语言里面不存在智能指针,我们需要自己创建智能指针。 下面我们开始正式的编写可复用库的程序,开发环境为Qt creator,首先给出智能指针的程序如下: 1 #ifndef SMARTPOINTER_H 2 #define SMARTPOINTER_H 3 4 namespace DTLib 5 { 6 7 template <typename T> 8 class SmartPointer 9 { 10 protected: 11 T *m_pointer; 12 13 public: 14 SmartPointer(T *p = NULL) 15 { 16 m_pointer = p; 17 } 18 19 SmartPointer(const SmartPointer<T>& obj) 20 { 21 m_pointer = obj.m_pointer; 22 23 const_cast<SmartPointer<T>&>(obj)

C++新特性之智能指针(一)——shared_ptr

女生的网名这么多〃 提交于 2020-03-10 06:12:32
智能指针之shared_prt 为啥要有智能指针,因为要自己手动分配内存还要自己释放回收,太麻烦,万一忘记了还很容易造成内存泄漏。所以,类似与java内存托管的智能指针来了,C11很重要,使用频率也很高的一个特性。shared_ptr遵循共享资源,多个智能指针对象可以共享这一块资源,the wonderful world comes from sharing. 一、创建以及初始化 std::shared_ptr<int> p1; //创建一个int类型智能指针并且不赋值 std::shared_ptr<int> p2(new int (123));//创建一个int类型智能指针,同时new一个int的对象给它 std::shared_ptr<int> p3 = p1;//拷贝初始化,p3与p1指向相同的内容 std::shared_ptr<int> p4 = std::make_shared<int>();//采用make_shared初始化,在动态内存中创建一个对象给它 std::shared_ptr<int> p5 = std::make_shared<int>(456); //采用make_shared初始化,在动态内存中创建一个对象给它,并初始化为456 std::shared_ptr<int> p6; p6.reset(new int(789));/

如何使用C++智能指针,及注意事项。

核能气质少年 提交于 2020-03-09 06:11:15
1、基础介绍 a、智能指针是 行为像指针的类对象 ,其包含一些功能有助于处理动态内存。 b、使用智能指针需包含 <memory> 头文件。 c、四个智能指针分别为: auto_ptr:C++11抛弃,用unique_ptr代替。 unique_ptr:C++11新增, 建立所有权,只能一个指针拥有指定对象,赋值操作会转移对象所有权 。 shared_ptr:C++11新增, 建立引用计数,可以多个指针拥有一个对象,计数器归零时才调用delete 。 weak_ptr:C++11新增,没了解。 2、如何定义智能指针对象 只能用于堆上内存 # include <memory> # include <string> 1 、 auto_ptr < double > a1 = new double ( 5.2 ) ; double * a2 = new double ; a1 = a2 ; // 错误,智能指针的构造函数只接受普通指针作为参数, // 指针到对象的赋值类型不匹配。 2 、 int b1 = 123 ; unique_ptr < int > b2 ( & b1 ) ; // 错误,只能用于堆上内存 std :: string abc = "asjdhasj" ; unique_ptr < std :: string > b3 ( & abc ) ; //错误,b3过期时, //

Effective C++ 学习笔记

别等时光非礼了梦想. 提交于 2020-03-08 13:46:07
1. 基础部分 Item 1: View C++ as a federation of languages. 对于内建类型,按值传递优于按引用传递,对于自定义类型则相反。 C++可视为4中子语言的联合:C,Object-Oriented C++,Template C++和STL。 Item 2: Prefer consts, enums, and inlines to #defines. 只有整型常量可以在类声明里面初始化: class Klass { const static int num = 1 ; //也可只声明,在定义文件中,即类外部定义、初始化; }; enum类型也可以在类内部初始化。 Item 3: Use const whenever possible. 对于指针p,const在 * 左边时,p指向的值为常量,const出现在 * 右边时,p指向的地址为常量。 const int * p1 ; int const * p2 ; int * const p3 ; ​ //以上代码,p1和p2一样,其指向的值为常量;p3指向的地址为常量 如果类Klass有同名的两个成员函数foo,其中一个为const类型,那么const实列优先调用const版的foo。 const函数不能改变非static的成员变量。 mutable修饰的成员,在const函数中也可以改变其值。

5.2 智能指针(smart pointer)

点点圈 提交于 2020-03-05 08:26:34
于头文件<memory> 1. shared_ptr实现共享拥有(shared ownership),标准库还提供了weak_ptr bad_weak_ptr和enable_shared_from_this等辅助类 2. unique_ptr实现独占式拥有(exclusive ownership/strict ownership), 3. 特点 shared_ptr和weak_ptr内部需额外的辅助对象(引用计数器等),因此无法完成一些优化操作 unique_ptr不需要这些额外的开销(unique_ptr特殊的构造和析构、copy语义的消除),unique_ptr消耗的内存和native pointer相同,还可使用function object(包括lambda)作为deleter达成最佳优化,甚至零开销。 smart pointer并不保证线程安全,虽然它有适用某些保证。 目录 share_ptr weak_ptr unique_ptr share_ptr shared_ptr基本使用 //1. 直接初始化 shared_ptr<string> test(new string("nico")); shared_ptr<string> test{new string("nico")}; //2. 使用便捷函数make_shared(),快、安全、使用一次分配 shared