Pointer

示例

#include <iostream>

using namespace std;

int main () {
    int i = 6;
    int *p_i = &i;
    cout << "  i : " << i << endl;
    cout << "  &i: " << &i << endl;
    cout << "p_i : " << p_i << endl;
    cout << "*p_i: " << *p_i << endl;
    return 0;
}

/** Output
  i : 6
  &i: 0x7ffeee386644
p_i : 0x7ffeee386644
*p_i: 6
*/

指针和引用

对比

  • 指针是一个实体,需要分配内存空间。引用只是变量的别名,不需要分配内存空间。

  • 引用在定义的时候必须进行初始化,并且不能够改变。指针在定义的时候不一定要初始化,并且指向的空间可变。

  • 有多级指针,但是没有多级引用,只能有一级引用。

  • 指针支持多种操作,比如++。

  • sizeof 引用得到的是所指向的变量(对象)的大小,而sizeof 指针得到的是指针本身的大小。

  • 引用访问一个变量是直接访问,而指针访问一个变量是间接访问。

智能指针

智能指针可以很好地解决:

  • 内存泄漏

    • 用动态存储分配函数(如malloc)动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元,直到程序结束

    • 内存泄漏是指堆内存泄漏

  • 悬挂指针

    • 未初始化的指针

      • 指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的

    • 未清零的指针

      • 指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针

四种智能指针

智能指针的原理都是RAII(Resource Acquisition Is Initialization),即在构造的时候获取资源,在析构的时候释放资源。

为了使用智能指针,需要引入头文件 #include <memory>

auto_ptr

c++98

解决内存泄漏问题

解决浅拷贝导致的指针悬挂问题

需要注意的问题

  • 所有权转移

    • auto_ptr transfers the ownership when it is assigned to another auto_ptr. This is really an issue while passing the auto_ptr between the functions. Say, I have an auto_ptr in Foo( ) and this pointer is passed another function say Fun( ) from Foo. Now once Fun( ) completes its execution, the ownership is not returned back to Foo.

  • 多个auto_ptr不能同时拥有同一个对象

  • 不能用auto_ptr管理数组指针

  • auto_ptr不可做为容器(vector, list, map)元素

unique_ptr

  • C++ 11 引入

基本操作

  • get()

    • 获得原生指针

  • reset()

    • 重置,显式释放资源

  • reset(new X)

    • 重置,重新指定对象

  • release()

    • 释放所有权到某一原生指针上

可以通过std::move将所有权由一个unique_ptr对象转移到另一个unique_ptr对象上。

禁止赋值和复制

unique_ptr禁止赋值和复制,“唯一”地拥有其所指对象,同一时刻只能有一个unique_ptr实例指向给定对象。也就是说模板类unique_ptr的copy构造函数以及等号(“=”)操作符是无法使用的。

管理数组指针

做容器元素

shared_ptr

​ shared_ptr has the notion called shared ownership. The goal of shared_ptr is very simple: Multiple shared pointers can refer to a single object and when the last shared pointer goes out of scope, memory is released automatically. 从上面这段英文可以看出,shared_ptr是共享所有权的,其内部有一个计数机制。

使用

  • get():获取原生指针

  • reset():重置,显式释放资源

  • reest(new X):重新指定对象

  • unique():检测对象管理者是否只有一个shared_ptr实例

在shared_ptr的RAII实现机制中,默认使用delete实现资源释放,也可以定义自己的函数来释放,比如当其管理数组指针时,需要delete[],这时就需要自定义释放函数。自定义释放的方法有两种:lambda表达式和括号操作符的重载。

另外可以通过dynamic_pointer_cast实现继承中的转换,具体见下例。

  • shared_ptr对象的引用是强引用(stong_ref)

最后更新于