美文网首页C++
智能指针

智能指针

作者: saviochen | 来源:发表于2017-06-17 11:01 被阅读161次

内存类型分类

1 静态内存

静态内存用来保存局部static对象,类static数据成员,以及定义在任何函数之外的变量。

2 栈内存

栈内存用来保存定义在函数内的非static对象。分配在静态内存和栈内存的变量由编译器自动创建和销毁。

3 堆内存(自由空间)

用来存储动态内存,动态对象的创建和销毁都由代码显式操作。

智能指针

C++中内存的管理是通过newdelete完成的,由于内存的释放容易遗漏,所以内存泄漏时常发生。

为了更容易且更安全地使用动态内存,新标准在memory头文件中定义了shared_ptrunique_ptrweak_ptr三种智能指针来管理动态内存。

1 shared_ptr

1.1 使用说明

智能指针也是模板,需要提供所指向的对象,默认初始化的智能指针中保存着一个空指针。

shared_ptr<string> p1;    //可以指向string类型
shared_ptr<list<int>> p2; //可以指向list<int>类型

if(p1 && p1->empty())   //如果p1为空,则将“hi”赋予string
        *p1 = "hi";
1.2 shared_ptr和unique_ptr都支持的操作
p.get();//返回p中保存的指针,当智能指针释放了其对象,返回的指针所指向的对象也被销毁了
swap(p,q);  //交换p和q中指针
q.swap(p);  //同上

局部shared_ptr离开其作用域,引用计数会递减,当引用计数为0时,就会自动释放它所管理的内存。

1.3 仅shared_ptr支持的操作
make_shared<T>(args);  //返回一个shared_ptr指向一个T对象,并用args初始化对象
shared_ptr<T> p(q);  //p是q的拷贝,此操作递增q中计数器
p = q;  //递减p中计数器,递增q中计数器
p.unique();  //若p.use_count()为1,返回true,否则false
p.use_count();  //返回指针的引用计数,一旦计数为0,指针会释放自己管理的对象。
1.4 使用动态内存的三个原因
  • 程序不知道自己需要使用多少对象
  • 程序不知道所需对象的准确类型
  • 程序需要在多个对象之间共享数据

以下是由于第三个原因使用动态内存的例子

template<typename T>
class Test{
public:
    Test():data(make_shared<vector<T>>()){}
    Test(std::initiallizer_list<T> li):data(make_shared<vector<T>>(li)){}//列表初始化
    void pop_back() {data->pop_back();}
    T& top() const {return data->back();}
    bool empty() const {return data->empty();}
    size_t size() const {return data->size();}
    void push_back(const T& d){data->push_back(d);}
private:
    shared_ptr<vector<T>> data;
};
1.5 new和delete动态用法
string *s = new string;
string *s = new string("2333");
auto p = new auto(obj);//括号中必须只有单一初始化器才能这么用
auto p = new auto({a,b});//错误用法
//正常情况下,new失败会抛出std::bad_alloc异常
int * p = new (nothrow) int;//若分配失败,返回空指针,称为定位new
delete p;
delete []p;

shared_ptr<int> p(new int(10));//正确用法
shared_ptr<int> p = new int(10);//错误用法,必须使用直接初始化
shared_ptr<int> f(){
    return new int;//不允许隐式转换,错误用法
}
shared_ptr<int> f(){
    returb shared_ptr<int>(new int);//智能指针式explicit的,正确用法
}
1.6 定义和改变shared_ptr
1)shared_ptr<T> p(q);
p管理内置指针q所指向的对象,q必须指向new分配的内存,且能转换成T*类型

2)shared_ptr<T> p(u);
p从unique_ptr u哪里接管对象的所有权,并将u置为空

3)shared_ptr<T> p(q,d);
p接管内置指针q所指向对象的所有权,p将使用可调用对象d来代替delete

4)shared_ptr<T> p(p2,d);
p是shared_ptr p2的拷贝,并p调用可调用对象d来代替delete

5)p.reset();
如果p是唯一指向对象的shared_ptr,reset会释放此对象

p.reset(q);
若传递了可选的参数内置指针q,会令p指向q,否则将p置空

p.reset(q,d);
若还传递了可选参数d,将会调用d而不是delete释放q

//注意:
//1. 虽然C++提供了内置指针和智能指针的转换,但是不要混用两种指针
//2. 不要使用get初始化另一个智能指针或为智能指针赋值
//3. 当将shared_ptr绑定到一个普通指针时,内存管理的责任已经交给了此shared_ptr,
//不能再使用内置指针来访问原来指向的内存了
//4. shared_ptr不支持下标运算法,只能使用点和箭头运算符

2 unique_ptr

shared_ptr不同的是,某个时刻只能有一个unique_ptr指向一个给定对象,当unique_ptr被销毁时,它所指向的对象也被销毁。定义一个unique_ptr时,必须将它绑定到一个new返回的指针上。

unique_ptr<double>  p1;
unique_ptr<int> p2(new int(43));

因为一个unique拥有一个对象,所以它不支持普通的拷贝或赋值操作,除上文所提到的操作外,unique_ptr还支持:

1)unique_ptr<T,D> u2;
定义一个空的u2,u2会使用一个类型为D的可调用对象来释放它的指针

2)unique_ptr<T,D> u(d);
定义一个空的u,指向类型为T的对象,用类型为D的对象d代替delete

3)u = nullptr;
释放u指向的对象,将u设为空

4)u.release();
u放弃对指针的所有权,返回指针,并将u置为空

5)u.reset();
释放u指向的对象

u.reset(q);
如果提供了内置指针q,则令u指向这个对象,否则将u置空

u.reset(nullptr);
//注意:unique_ptr只能使用下标运算符,不能使用点和箭头运算符

3 weak_ptr

shared_ptr类似于操作系统中的硬链接,weak_ptr则与软链接相似。weak_ptr是一种不控制所指向对象生存周期的智能指针,它指向一个由shared_ptr管理的对象,将一个weak_ptr绑定到shared_ptr不会改变shared_ptr的引用计数。

weak_ptr<T> w;
weak_ptr<T> w(sp);
w = p;//p 为weak ptr或者shared ptr
w.reset();//将w置为空
w.use_count();
w.expired();//若w.use_count()为0,则为true,否则false
w.lock();//若expired返回true,则返回一个空shared_ptr,否则指向w的shared_ptr

相关文章

  • 目录

    智能指针(1) 智能指针(2) 智能指针(3) 智能指针之使用 容器 - vector(1) 容器 - vecto...

  • 智能指针到Android引用计数

    智能指针 LightRefBase RefBaseStrongPointerWeakPointer 智能指针 这是...

  • C++面试重点再梳理

    智能指针 请讲一下智能指针原理,并实现一个简单的智能指针 智能指针其实不是一个指针。它是一个用来帮助我们管理指针的...

  • C++研发工程师笔试题/面试题(1-10)

    1. (1) 简述智能指针的原理;(2)c++中常用的智能指针有哪些?(3)实现一个简单的智能指针。 简述智能指针...

  • 第十六章 string类和标准模板库(2)智能指针模板类

    (二)智能指针模板类 智能指针是行为类似指针的类对象,但这种对象还有其他便于管理内存的功能。 1.使用智能指针 (...

  • Rust for cpp devs - 智能指针

    与 cpp 类似,Rust 也有智能指针。Rust 中的智能指针与引用最大的不同是,智能指针 own 内存,而引用...

  • C++ 引用计数技术及智能指针的简单实现

    1.智能指针是什么 简单来说,智能指针是一个类,它对普通指针进行封装,使智能指针类对象具有普通指针类型一样的操作。...

  • 智能指针

    1. 什么是智能指针? 智能指针是行为类似于指针的类对象,但这种对象还有其他功能。 2. 为什么设计智能指针? 引...

  • chrome中智能指针使用

    chrom中智能指针的概述和作用 chrome中智能指针的用法和总结 包含如下四种智能指针:scoped_ptr ...

  • c++智能指针用法

    智能指针是什么 智能指针是c++中有四个智能指针:auto_ptr、shared_ptr、weak_ptr、uni...

网友评论

    本文标题:智能指针

    本文链接:https://www.haomeiwen.com/subject/xnqxxxtx.html