logo头像
Snippet 博客主题

RAII

What is RAII?

1
2
把资源和对象的生命周期绑定,对象创建获取资源,对象销毁释放资源。  
把底层的资源管理提升到对象生命周期管理的层次。

Why C++ chooses RAII instead of normal GC

1
和GC相比,RAII达到了和手动释放资源一样的实时性,因此可以承担底层开发的重任

unique-onwership smart pointer

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
unique-onwership smart pointer ? 只能一个对象拥有资源 ? 转让所有权 ?
move-sematics ? 避免拷贝 ?

使用时智能指针是个栈对象,里面包了一个指针,对象在出作用域的时候会析构,然后析构里面对我们包裹的指针进行释放

#pragma once
#include <memory>

namespace hinata {

template <typename T, typename D> // D = default_delete<T>
class unique_ptr : public std::_Unique_ptr_base<T, D>
{
public:
typedef unique_ptr<T, D> Myt_;
// 暂时用VS提供的,日后在写两个类,或者一个加一个内部 pointer
// 也可以把 pointer 写到这里来 // 暂时简单点,防止脑袋烧爆
typedef _Unique_ptr_base<T, D> Mybase_;
// 下划线风格有时候好脑残,
typedef typename Mybase_::pointer pointer_;
// 暂时不用先放这里 // 轮子不好造啊
typedef T element_type_;
typedef D deleter_type_;

using Mybase_::get_deleter;

// constructors // 暂时就先提供2个
constexpr unique_ptr() noexcept
: Mybase_(pointer_())
{ // constexpr(常量表达式)用于修饰类的构造函数,
// 即保证如果提供给该构造函数的参数都是constexpr,
// 那么产生的对象中的所有成员都会是constexpr,
// 该对象也就是constexpr对象了,可用于各种只能使用constexpr的场合。
// note,constexpr构造函数必须有一个空的函数体,即所有成员变量的初始化都放到初始化列表中。
static_assert(!is_pointer<D>::value,
"unique_ptr constructed with null deleter pointer")
}

explicit unique_ptr(pointer_ p) noexcept
: Mybase_(pointer_())
{ // null pointer construct
static_assert(!is_pointer<D>::value,
"unique_ptr constructed with null deleter pointer")
}

unique_ptr(unique_ptr&& right) _NOEXCEPT
: Mybase_(right.release(),
::std::forward<_Dx>(right.get_deleter()))
{ // construct by moving _Right
}

// destructor
~unique_ptr() noexcept
{
if (get() != pointer_())
this->get_deleter()(get());
}

// assignment // assign by moving 省略
// 暂时就提供一个 赋空值的
Myt_& operator=(nullptr_t)
{
reset();
return (*this);
}

// observers
pointer_ operator->() const noexcept
{ // return pointer to class object
return pointer_();
}

pointer_ get() const noexcept
{ // return pointer to object
return (this->_Myptr());
}

explicit operator bool() const noexcept
{ // test for non-null pointer
return (get() != pointer());
}

// 先使用基类的,应该自己练习写一个的
//// Returns: A reference to the stored deleter.
//deleter_type& get_deleter() noexcept;
//const deleter_type& get_deleter() const noexcept;

// modifiers
pointer_ release() noexcept
{ // yield ownership of pointer
pointer_ ans = get();
this->_Myptr() = pointer();
return (ans);
}

void reset(pointer_ ptr = pointer_()) noexcept
{ // establish new pointer
pointer old = get();
this->_Myptr() = ptr;
if (old != pointer_())
this->get_deleter()(old);
}

// void swap(unique_ptr& u) noexcept;

// disable copy from lvalue
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;

private:

};

// operator == , != , > , >= , < , <=
template <class T1, class D1, class T2, class D2>
bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{
return false;
}
}