智能指针

智能指针

岁酱吖の 提交于 2020-03-05 07:27:53
title: 智能指针 date: 2018-04-02 15:21:32 categories: C/C++ tags: 指针 为什么使用动态指针? 在C++中,动态内存的管理是通过一对运算符来完成的: new: 在动态内存中为对象分配空间并返回一个指向该对象的指针,同时可以对这个对象初始化。 delete: 接受一个动态对象的指针,销毁该对象并释放与之关联的内存。 这样动态内存的使用就很容易出现问题: 忘记释放内存(delete)就会产生内存泄漏的问题。 过早释放内存(在还有指针引用该内存的时候就释放了它)就会产生引用非法内存的指针。 为了防止出现这种情况,更容易更安全地使用动态内存, 自C++11开始提供了两种智能指针类型来管理动态对象。 什么是智能指针? 智能指针是存储指向动态分配(堆)对象指针的类。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。 智能指针的原理是什么? 资源分配即初始化RAII(Resource Acquisition Is Initialization):RAII 的做法是使用一个对象,在其构造时获取资源,在对象生命期控制对资源的访问使之始终保持有效,最后在对象析构的时候释放资源。 定义一个类来封装资源的分配和释放,在构造函数完成资源的分配 和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放。

C++ 智能指针 auto_ptr 和 shared_ptr

空扰寡人 提交于 2020-03-04 17:19:04
首先,如果你不知道什么是智能指针,请先移步: C++智能指针简单剖析 1.auto_ptr 1 #ifndef AUTO_PTR_H 2 #define AUTO_PTR_H 3 4 template<typename T> 5 class auto_ptr 6 { 7 public : 8 //使用explicit关键字避免隐式转换 9 explicit auto_ptr(T* p=0); 10 ~auto_ptr(); 11 12 //使用另一个类型兼容的auto_ptr来初始化一个新的auto_ptr 13 template<typename U> 14 auto_ptr(auto_ptr<U>& rhs); 15 16 template<typename U> 17 auto_ptr<T>& operator=(auto_ptr<U>& rhs); 18 19 T& operator*() const; 20 T* operator->() const; 21 22 //返回原始对象的指针 23 T* get() const; 24 //放弃指针的所有权 25 T* release(); 26 //删除原有指针并获得指针p的所有权 27 void reset(T* p=0); 28 29 private: 30 T* pointee; 31 }; 32 33

第二讲 auto_ptr智能指针

六月ゝ 毕业季﹏ 提交于 2020-03-04 17:18:30
auto_ptr 不可被共享,只能指向一个对象 auto_ptr在构造时获取对某个对象的所有权(ownership),在析构时释放该对象。我们可以这样使用auto_ptr来提高代码安全性: int* p = new int(0); auto_ptr<int> ap(p); 从此我们不必关心应该何时释放p, 也不用担心发生异常会有内存泄漏。 这里我们有几点要注意: 1) 因为auto_ptr析构的时候肯定会删除他所拥有的那个对象,所有我们就要注意了,一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象。像这样: int* p = new int(0); auto_ptr<int> ap1(p); auto_ptr<int> ap2(p); 因为ap1与ap2都认为指针p是归它管的,在析构时都试图删除p, 两次删除同一个对象的行为在C++标准中是未定义的。所以我们必须防止这样使用auto_ptr. 2) 考虑下面这种用法: int* pa = new int[10]; auto_ptr<int> ap(pa); 因为auto_ptr的析构函数中删除指针用的是delete,而不是delete [],所以我们不应该用auto_ptr来管理一个数组指针。 3) 构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型。 4) 因为C+

boost库:智能指针

心已入冬 提交于 2020-03-04 16:53:05
1. C98里的智能指针 std::auto_ptr ,本质上是一个普通的指针,通过地址来访问你一个动态分配的对象,初始化时需要传递一个由new操作符返回的对象地址。 std::auto_ptr的析构函数会调用delete操作符,释放掉其包含的对象内存。 智能指针的原理基于一个常见的习语:RAII(资源申请即初始化)。智能指针确保在任何情况下,动态分配的内存都能够得到正确释放,包括程序因为 异常而中断,原本用于释放内存的代码被跳过的场景。用一个动态分配的对象的地址来初始化智能指针,因为析构函数总是会被执行的,则包含的内存就会被释放。 2. 作用域指针 一个作用域指针独占一个动态分配的对象。其类名为:boost::scoped_ptr,一个作用域指针不能传递它所包含的对象的所有权到另一个作用域指针。作用域指针只是简单保存和独占一个内存地址,在不需要所有权传递的时候应该优先使用boost::scoped_ptr。 由于boost::scoped_ptr的析构函数中使用delete操作符来释放所包含的对象,因此boost::scoped_ptr不能用动态分配的数组来做初始化。 3. 作用域数组 与作用域指针相似。不同在于:作用域数组的析构函数使用delete[]操作符来释放所包含的对象,因此该操作符只能用于数组对象,所以作用域数组必须通过动态分配的数组来初始化。 4. 共享指针

Boost学习笔记-智能指针

ぐ巨炮叔叔 提交于 2020-03-04 16:52:47
1. 智能指针 scoped_ptr 只在作用域内生效,离开作用域既释放资源,不能复制和赋值。类似于标准库的auto_ptr,但它相对于auto_ptr的优势在于,他的要求更严格,使用起来更安全。auto_ptr拥有转移语义,当使用了赋值和复制操作时可能操作未定义行为。 scoped_array scoped_array 的数组形式,区别在于他管理的对象是用new []分配,同时释放时用delete[],能正确的释放数组对象。不能用*和->操作符,支持[]操作符方式解引用。scoped_array不推荐使用,因为使用麻烦,可以用vector代替。 shared_ptr shared_ptr是一个引用计数型智能指针,当计数为0时自动释放管理的资源。支持*和->指针操作行为,提供隐式bool类型转换用于指针有效性判断。通过get()方法可以获取原始指针。 shared_ptr有两个专门的函数来检查引用计数。unique()指示该指针是否是对象的唯一管理者。use_count()指示对象正在由多少智能 指针引用。 shared_ptr支持比较运算,基于内部保持的指针实现。 通过make_shared<T>()函数可以使用工厂创建share_ptr对象,而省去显示的new调用。 shared_ptr支持定制删除器,可以指定share_ptr管理的对象在析构时自动调用删除器

[zz]Boost智能指针——scoped_ptr

非 Y 不嫁゛ 提交于 2020-03-04 16:50:51
boost::scoped_ptr 和 std::auto_ptr 非常类似,是一个简单的智能指针,它能够保证在离开作用域后对象被自动释放。下列代码演示了该指针的基本应用: #include <string> #include <iostream> #include <boost/scoped_ptr.hpp> class implementation { public : ~implementation() { std::cout << "destroying implementation/n" ; } void do_something() { std::cout << "did something/n" ; } }; void test() { boost::scoped_ptr<implementation> impl( new implementation()); impl->do_something(); } void main() { std::cout<< "Test Begin ... /n" ; test(); std::cout<< "Test End./n" ; } 该代码的输出结果是: Test Begin ... did something destroying implementation Test End. 可以看到:当 implementation

智能指针scoped_ptr

强颜欢笑 提交于 2020-03-04 16:50:31
对应C++11中的 unique_ptr #include <iostream> #include <memory> class foo { public: foo() { std::cout<<"constructor"<<std::endl;} ~foo() { std::cout<<"destructor"<<std::endl; } void doit() { std::cout<<"do"<<std::endl; } }; int main() { std::unique_ptr<foo> sf(new foo); sf->doit(); (*sf).doit(); sf.reset(new foo); sf->doit(); return 0; }    scoped_ptr的所有权更加严格,不允许转让,对其赋值和拷贝都是不合法行为,因而显得更轻巧和快捷。 scoped_ptr重载了operator*()和operator->()解引用操作符*和箭头操作符->,因此可以把scoped_ptr对象如同指针一样使用。如果scoped_ptr保存的空指针,那么这两个操作的行为未定义。 scoped_ptr不能在两个scoped_ptr之间、scoped_ptr与原始指针之间或空指针之间进行了相等或不相等测试。operator ==和operator !=都被声明为私有。

智能指针学习笔记

寵の児 提交于 2020-03-04 16:43:02
智能指针学习笔记 本文介绍智能指针的使用。智能指针是c++ 中管理资源的一种方式,用智能指针管理资源,不必担心资源泄露,将c++ 程序员 从指针和内存管理中解脱出来,再者,这也是c++发展的趋势(这话不是我说的,见《Effective c++》和《c++实践编程》),应该认真学习一下。 智能指针中,最有名的应该数auto_ptr,该智能指针已经被纳入标准库,只需要包含<memory>头文件即可以使用,另外,TR1文档定义的shared_ptr和weak_ptr也已经实现(我用的gcc版本是gcc 4.6.1),它们的头文件是<tr1/memory> 。除此之外,还有几个好用的智能指针,不过它们属于boost库,不属于STL ,所以,用不用得到,根据自己的需要。不过,了解一下总无妨,正所谓”功不唐捐”嘛。 下面分别介绍auto_ptr,scoped_ptr,scoped_array,shared_ptr,shared_array, weak_ptr 和 intrusive_ptr 。 ##2. auto_ptr ###2.1 为什么要用智能指针 在介绍第一个智能指针之前,先介绍下为什么要使用智能指针。先看下面这个函数: void f() { classA* ptr = new classA; // create an object explicitly ... // perform

Boost智能指针——shared_ptr

梦想的初衷 提交于 2020-03-04 16:32:25
boost::scoped_ptr 虽然简单易用,但它不能共享所有权的特性却大大限制了其使用范围,而 boost::shared_ptr 可以解决这一局限。顾名思义,boost::shared_ptr是可以共享所有权的智能指针,首先让我们通过一个例子看看它的基本用法: #include <string> #include <iostream> #include <boost/shared_ptr.hpp> class implementation { public : ~implementation() { std::cout << "destroying implementation\n" ; } void do_something() { std::cout << "did something\n" ; } }; void test() { boost::shared_ptr<implementation> sp1( new implementation()); std::cout<< "The Sample now has " <<sp1.use_count()<< " references\n" ; boost::shared_ptr<implementation> sp2 = sp1; std::cout<< "The Sample now has " <<sp2.use

C++_十六章_智能指针_关于string对象、string指针和空指针的总结_关于智能指针相互赋值会导致出现空字符的问题_标准模板库

允我心安 提交于 2020-02-28 10:55:18
目录 1、智能指针 2、关于string对象、string指针和空指针的总结 3、关于智能指针相互赋值会导致出现空字符的问题 4、标准模板库 1、智能指针 01) 在使用new为指针分配内存空间的时候,有可能会出现忘记添加delete或者是没有忘记但不执行delelte的情况 ,此时就会导致内存泄露,例如如下情况: 1 void remodel(std::string & str) 2 { 3 std::string * ps = new std::string(str); 4 double * pd1 = new double[8]; //new返回一个可以存储8个double行数据的地址,pd1是一个指针 5 ... 6 if(weird_thing()) 7 throw exception(); //如果执行此句,那么就有可能不执行下面的delete 8 str = *ps; 9 delete ps; 10 return; 11 } delete有可能不会被执行的情况 02)使用智能指针 (1)这三个智能指针模板(auto_ptr、unique_ptr和shared_ptr)都定义了类似指针的对象,可以将new获得的地址赋给这些对象。当智能指针过期时,其析构函数将使用delete  来释放内存。下图说明了常规指针和auto_ptr之间的差别.(unique