[c++11]智能指针类型¶
参考:Smart Pointers (Modern C++)
使用原始指针需要手动操作内存分配和删除,同时需要密切关注指针引用。在现代C++
编程中,标准库包括智能指针(smart pointer
),用于确保程序不受内存(free of memory
)和资源泄漏(resource leaks
)的影响,并且是异常安全(exception-safe
)的
头文件¶
智能指针的声明位于头文件<memory>
原理¶
C++
没有单独的垃圾收集器(garbage collector
)在后台运行,是通过标准C++
范围规则(scoping rule
)来管理内存,以便运行时环境更快、更高效
智能指针是在栈上声明的类模板,通过使用指向堆分配对象的原始指针进行初始化。智能指针初始化后,它拥有原始指针。这意味着智能指针负责删除原始指针指定的内存。智能指针析构函数包含对delete
的调用,并且由于智能指针在栈上声明,因此当智能指针超出作用域时将调用其析构函数,即使在栈上的某个位置引发异常
使用熟悉的指针运算符->
和*
访问封装的指针,智能指针类重载这些运算符以返回封装的原始指针
类别¶
学习3
种不同的智能指针:
unique_ptr
shared_ptr
weak_ptr
编程规范¶
智能指针对原始指针进行了封装,能够保证其安全使用,与此同时也造成了效率的小小降低
- 大多数情况下,当初始化原始指针或资源句柄以指向实际资源时,立即将指针传递给智能指针
- 原始指针只用于有限范围、循环或辅助函数的小代码块中。在这些代码块中,性能至关重要,并且不可能混淆所有权
- 始终在单独的代码行上创建智能指针,而不是在参数列表中,这样就不会由于某些参数列表分配规则而发生细微的资源泄漏
使用智能指针的基本步骤如下:
- 声明智能指针作为自动(
automatic
)或局部(local
)变量(不要对智能指针使用new
或malloc
表达式) - 在类型参数中,指定封装指针的指向类型
- 在智能指针构造函数中传递原始指针(已指向对象)(一些实用程序函数或智能指针构造函数可以辅助执行此操作)
- 使用重载的
*
或->
运算符访问对象 - 让智能指针删除对象
示例¶
创建结构体S
,分别使用原始指针rptr
和智能智能sptr
创建对象,输入函数print
进行打印
struct S {
S(char a, int b) : a(a), b(b) {}
char a;
int b;
};
void print(const struct S &ptr) {
cout << ptr.a << " " << ptr.b << endl;
}
int main(int argc, char *argv[]) {
std::unique_ptr<struct S> sptr(new struct S('b', 3));
auto *rptr = new struct S('b', 3);
print(*sptr);
print(*rptr);
delete (rptr);
}