- 前言
- 智能指针的作用
- 智能指针的特点
- shared_ptr
- 共享指针
- 循环引用
- unique_ptr
- weak_ptr
- 手写一个shared_ptr类
- 后记
之前分别学习了C++的三种智能指针shared_ptr,unique_ptr,weak_ptr的使用,本篇来做一个总结。
智能指针的作用C/C++的一大特色就是指针,常用的堆指针分配方式需要手动进行内存空间的释放。
智能指针的出现为堆内存的管理提供了方便,降低了内存泄漏的风险。
智能指针的特点智能指针实际上是通过类把堆指针进行封装,并通过重载运算符使得智能指针对象具有了类似普通指针的使用方式。
也就是说智能指针的使用类似普通指针,而实质上是一个对象。
智能指针最大的作用就是在合适的时间自动释放内存空间,防止出现内存泄漏的问题。
智能指针的生命周期与其作用域相关,超过作用域后将被销毁。
shared_ptr 共享指针shared_ptr智能指针可以共享同一个普通指针,并具有引用计数块。
注意:shared_ptr的指针共享只能通过对象赋值操作、拷贝构造初始化实现。如果将一个普通指针分别给两个shared_ptr对象初始化,则会出现double free的问题。
因此,使用shared_ptr时,尽量不要与普通堆指针混用。
循环引用循环引用时shared_ptr的常见问题。可以通过weak_ptr进行调试。
unique_ptrunique_ptr智能指针独享内部指针的所有权,因此没有拷贝构造函数。
unique_ptr相比shared_ptr更适合指向数组,因为它重载了[]运算符:
std::unique_ptr vec(new int[8]);
vec[3] = 888;
weak_ptr
weak_ptr是shared_ptr的辅助指针,不具有普通指针的操作符。不能通过普通堆指针或nullptr构造。可以通过shared_ptr或者weak_ptr构造,但不会增加shared_ptr的引用计数。
weak_ptr常用于解决shared_ptr的循环引用问题。
手写一个shared_ptr类要理解智能指针,我自己手写了一个类似shared_ptr的类实现:
#include
#include
#include
class A;
class B;
template
class mySmartPointer
{
private:
T* ptr_;
size_t* counter_;
public:
explicit mySmartPointer(T* ptr=nullptr) {
ptr_ = ptr;
if (ptr != nullptr)
counter_ = new size_t(1);
else
counter_ = new size_t(0);
};
mySmartPointer(const mySmartPointer &p) {
ptr_ = p.ptr_;
counter_ = p.counter_;
if (p.ptr_ != nullptr)
(*counter_)++;
}
~mySmartPointer() {
(*this->counter_)--;
if ((*this->counter_) == 0)
{
delete this->ptr_;
delete this->counter_;
}
};
mySmartPointer& operator=(const mySmartPointer &p) {
if (ptr_ == p.ptr_)
{
return *this;
}
if (ptr_ != nullptr)
{
(*counter_)--;
if (*counter_ == 0)
{
delete ptr_;
delete counter_;
}
}
ptr_ = p.ptr_;
counter_ = p.counter_;
(*counter_)++;
return *this;
}
T& operator*() {
assert(this->ptr_ == nullptr);
return *(this->ptr_);
}
T* operator->() {
assert(this->ptr_ == nullptr);
return this->ptr_;
}
T* get() {
return ptr_;
}
int use_count() {
return *counter_;
}
bool unique() {
return bool(*counter_ == 1);
}
void reset(T* p=nullptr) {
if (ptr_ != nullptr)
{
(*counter_)--;
if (*counter_ == 0)
{
delete ptr_;
delete counter_;
}
}
ptr_ = p;
if (p != nullptr)
counter_ = new size_t(1);
else
counter_ = new size_t(0.);
}
};
class A
{
public:
std::shared_ptr b_;
public:
A(){
std::cout
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?