C++ 11 中有 unique_ptrshared_ptrweak_ptr 等智能指针(smart pointer),定义在<memory>中。可以对动态资源进行管理,保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。

名词 描述
unique_ptr 拥有管理内存的所有权,没有拷贝构造函数,只有移动构造函数,不能多个unique_ptr对象共享一段内存,可以自定义delete函数,从而支持delete [] 。
share_ptr 通过计数方式多个share_ptr可以共享一段内存,当计数为0的时候,所管理内存会被删除,可以自定义delete函数,从而支持delete[]。
weak_ptr 观察shared_ptr管理的内存对象 ,只观察但不拥有。成员函数lock返回shared_ptr对象,若对应内存已经删除,则shared_ptr对象==nullptr,weak_ptr对象可以拷贝构造,拷贝构造出来的对象和原对象观察的是同一段内存。成员函数reset可以解除对内存的观察,注意,是解除观察,并不会删除对应内存对象。可以避免因shared_ptr的循环引用而引起的内存泄露,见如下对比使用方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <memory>
#include <string>
#include <iostream>

using namespace std;

class B;
class A
{
public:
shared_ptr<class B> m_spB;
};


class B
{
public:
shared_ptr<class A> m_spA;
};

class D;
class C
{
public:
weak_ptr<class D> m_wpD;
};


class D
{
public:
weak_ptr<class C> m_wpC;
};


void test_loop_ref()
{
weak_ptr<class A> wp1;

{
auto pA = make_shared<class A>();
auto pB = make_shared<class B>();

pA->m_spB = pB;
pB->m_spA = pA;

wp1 = pA;
}

cout << "wp1 reference number: " << wp1.use_count() << "\n";// 存在内存泄露,打印如下,wp1 reference number:1

weak_ptr<class C> wp2;
{
auto pC = make_shared<class C>();
auto pD = make_shared<class D>();

pC->m_wpD = pD;
pD->m_wpC = pC;

wp2 = pC;
}

cout << "wp2 reference number: " << wp2.use_count() << "\n";// 没有内存泄露,打印如下,wp2 reference number:0
}

int main()
{
//std::weak_ptr 用来避免 std::shared_ptr 的循环引用
test_loop_ref();

return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <memory>

// std::shared_ptr 是一种智能指针,它能够记录多少个 shared_ptr 共同指向一个对象,
// 从而消除显式的调用 delete,当引用计数变为零的时候就会将对象自动删除
void shared_ptr()
{
std::shared_ptr<int> p = std::make_shared<int>(1);
auto p1 = std::make_shared<std::string>("pointer");

auto p2 = p;
auto p3 = p2;
auto p4 = p3.get();
std::cout << "p.use_count:" << p.use_count() << std::endl;
std::cout << "p1.use_count:" << p1.use_count() << std::endl;
std::cout << "p2.use_count:" << p2.use_count() << std::endl;
std::cout << "p3.use_count:" << p3.use_count() << std::endl;

p2.reset();
std::cout << "p.use_count:" << p.use_count() << std::endl;
std::cout << "p1.use_count:" << p1.use_count() << std::endl;
std::cout << "p2.use_count:" << p2.use_count() << std::endl;
std::cout << "p3.use_count:" << p3.use_count() << std::endl;
std::cout << "p2:" << p2 << std::endl; // error: p2 已 reset
std::cout << "p2:" << *p2 << std::endl; // error: p2 已 reset
}

// std::unique_ptr 是一种独占的智能指针,它禁止其他智能指针与其共享同一个对象,
// 从而保证代码的安全
void unique_ptr()
{
std::unique_ptr<int> up = std::make_unique<int>(2);
// auto up1 = up; // error
}

int main()
{
std::cout << "Smart Pointer!\n";

shared_ptr();

unique_ptr();
}