当前位置:网站首页>Smart pointer implementation conjecture
Smart pointer implementation conjecture
2022-07-30 12:53:00 【Jun Meng Ru Yan Brian】
Automatic memory management envisioned by strong and weak references,Only the part that manages memory is implemented,仍有许多C++11function could not be realized.
SharedPtr => std::shared_ptr
SentinelPtr => std::weak_ptr (Why take it this way,因为SentinelPtr Behaving more likeSharedPtr 的观察窗口)
首先,实现了SharedPtr, 这个很好理解.Reference counts whenever copy behavior occurs+1,Because the counter is shared among multiple objects,So the counter must also be a pointer.
难点在于,引入SentinelPtr后,同时保持SharedPtr Conditional control of behavior.
Comparatively speaking,We can think of strong references as counters of values,Then a weak pointer is equivalent to a counter of strong references.
欠缺:
(-) 功能还没完全实现,Just implemented the part involving counting.
(-) Counters are not thread safe
template<typename T>
class SentinelPtr;
template <typename T>
class SharedPtr {
size_t* ref_counter_ = nullptr;// 强引用计数器
T* val_ = nullptr; // 值引用
size_t * soft_ref_counter_ = nullptr; // 弱引用计数器
// template <T>
friend class SentinelPtr<T>;
public:
SharedPtr operator=(const SharedPtr& rhs) = delete;
SharedPtr():ref_counter_(nullptr), val_(nullptr), soft_ref_counter_(nullptr){
}
SharedPtr(T val) :val_(new T(val)), ref_counter_(new size_t(1)), soft_ref_counter_(new size_t(1)) {
}
SharedPtr(T* val_pointer) {
if (val_pointer != nullptr) {
val_ = val_pointer;
ref_counter_ = new size_t(1);
soft_ref_counter_ = new size_t(1);
}
else {
val_ = nullptr;
ref_counter_ = nullptr;
soft_ref_counter_ = nullptr;
}
}
SharedPtr(const SharedPtr<T>& rhs) {
// 歧义: The reference count itself must be incremented,constThe expression is a bit strange
if(val_ != rhs.val_) try_release();
soft_ref_counter_ = rhs.soft_ref_counter_;
ref_counter_ = rhs.ref_counter_;
val_ = rhs.val_;
// rhsConstructed by default
if (val_ == nullptr) return;
assert(soft_ref_counter_ != nullptr);
assert(ref_counter_ != nullptr);
(*soft_ref_counter_)++;
(*ref_counter_)++;
}
~SharedPtr() {
if (val_ == nullptr) return;
assert(ref_counter_ != nullptr);
assert(val_ != nullptr);
try_release();
soft_ref_counter_ = nullptr;
ref_counter_ = nullptr;
val_ = nullptr;
}
public:
size_t use_count()const {
if (ref_counter_) return *ref_counter_;
return 0;
}
private:
// 释放了val就return true
void try_release() {
// An object possibly constructed from a null pointer
if (!soft_ref_counter_) return;
// 弱引用计数, Pay later
(*soft_ref_counter_)--;
assert(ref_counter_ != nullptr);
(*ref_counter_)--;
// 强引用计数为0, 释放值
if (*ref_counter_ == 0) {
delete val_;
val_ = nullptr;
}
// 弱引用计数为0, Free all counters
if ((*soft_ref_counter_) == 0) {
delete ref_counter_;
delete soft_ref_counter_;
ref_counter_ = nullptr;
soft_ref_counter_ = nullptr;
}
}
};
template<typename T>
class SentinelPtr {
size_t* ref_counter_; // 强引用计数器
size_t* soft_ref_counter_; // 弱引用计数器(Equivalent to the reference count of a strong referrer)
T* val_; // 提升值
public:
SharedPtr<T> update() {
if (!soft_ref_counter_ || !ref_counter_) return SharedPtr<T>;
SharedPtr<T> ex;
ex.ref_counter_ = ref_counter_;
ex.soft_ref_counter_ = soft_ref_counter_;
ex.val_ = val_;
(*soft_ref_counter_)++;
(*ref_counter_)++;
return ex;
}
SentinelPtr(SharedPtr<T> sha_ptr) {
ref_counter_ = sha_ptr.ref_counter_;
soft_ref_counter_ = sha_ptr.soft_ref_counter_;
val_ = sha_ptr.val_;
if (soft_ref_counter_) {
assert(ref_counter_ != nullptr);
(*soft_ref_counter_)++;
}
else {
assert(ref_counter_ == nullptr);
assert(soft_ref_counter_ == nullptr);
assert(val_ == nullptr);
}
}
SentinelPtr(const SentinelPtr<T>& st_ptr) {
if(soft_ref_counter_ != st_ptr)
try_release();
ref_counter_ = st_ptr.ref_counter_;
soft_ref_counter_ = st_ptr.soft_ref_counter_;
val_ = st_ptr.val_;
if (soft_ref_counter_) {
assert(ref_counter_ != nullptr);
(*soft_ref_counter_)++;
}
else {
assert(ref_counter_ == nullptr);
assert(soft_ref_counter_ == nullptr);
assert(val_ == nullptr);
}
}
~SentinelPtr() {
try_release();
ref_counter_ = nullptr;
val_ = nullptr;
soft_ref_counter_ = nullptr;
}
/* size_t use_count() { if (!soft_ref_counter_ || !ref_counter_) return 0; return (*ref_counter_); } */
private:
void try_release() {
if (!soft_ref_counter_) return;
assert(ref_counter_ != nullptr);
(*soft_ref_counter_)--;
if (*soft_ref_counter_ == 0) {
delete soft_ref_counter_;
delete ref_counter_;
soft_ref_counter_ = nullptr;
ref_counter_ = nullptr;
}
}
};
int main()
{
// default ctor
{
SharedPtr<int> emp_ptr;
}
// ctor(val)
{
SharedPtr<int> ptr(4);
assert(ptr.use_count() == 1);
}
// ctor(valpointer)
{
SharedPtr<int> b(new int(4));
assert(b.use_count() == 1);
}
// dctr
{
SharedPtr<int> outer(4);
{
SharedPtr<int> inner(outer);
assert(outer.use_count() == inner.use_count());
assert(inner.use_count() == 2);
}
assert(outer.use_count() == 1);
}
{
SharedPtr<int> outer(4);
SentinelPtr<int> p = outer;
assert(outer.use_count() == 1);
}
return 0;
}
边栏推荐
- JS事件的相关特性以及原理
- 力扣——11.盛最多水的容器
- 【CVA估值训练营】如何快速读懂上市公司年报——第五讲
- Based on MySQL database, Redis cache, MQ message middleware, ES high availability scheme of search engine parsing
- Rust from entry to proficient 02-installation
- Execution order of select, from, join, on where groupby, etc. in MySQL
- 漫谈金丝雀部署(Canary Deployment)
- 奇异值分解(SVD)原理与在降维中的应用(附带例题讲解)(纯理论)
- C# 时间戳与时间的互相转换
- saltstack学习3模块
猜你喜欢

概率论的学习整理2:如何对随机实验的对象:“事件” 进行计数呢? 四种计数方法,不只是排列组合

京东二面痛遭中间件虐杀,30天学透这套中间件小册,挺进阿里

Rust from entry to proficient 02-installation

数据湖(十八):Flink与Iceberg整合SQL API操作

13-GuliMall 基础篇总结

【Kaggle:UW-Madison GI Tract Image Segmentation】肠胃分割比赛:赛后复盘+数据再理解

IO/multiplexing (select/poll/epoll)
![[SCTF2019]Flag Shop](/img/26/20e21ec873f41f2633703216453a44.png)
[SCTF2019]Flag Shop

Unity Beginner 6 - Simple UI production (blood bar production) and audio addition and NPC dialogue bubbles (2d)

北上广线下活动丨年底最不可错过的技术聚会都齐了
随机推荐
最基础01/完全背包
13-GuliMall 基础篇总结
[SCTF2019]Flag Shop
dolphinscheduler添加hana支持
Based on MySQL database, Redis cache, MQ message middleware, ES high availability scheme of search engine parsing
干货分享:小技巧大用处之Bean管理类工厂多种实现方式
RTSP/Onvif协议视频平台EasyNVR服务一键升级功能的使用教程
unity初学6——简易的UI制作(血条制作)和音频加入以及NPC的对话气泡(2d)
dolphinscheduler simple task definition and complex cross-node parameter transfer
并行化快速排序设想
【ASP.NET Core】选项类的依赖注入
A tutorial on how to build a php environment under win
[ASP.NET Core] Dependency Injection for Option Classes
物理服务器与虚拟机:主要区别和相似之处
Win11打不开exe应用程序怎么办?Win11无法打开exe程序解决方法
解码Redis最易被忽视的CPU和内存占用高问题
【MySQL系列】-B+树索引和HASH索引有什么区别
如何将EasyCVR平台RTSP接入的设备数据迁移到EasyNVR中?
【32. 图中的层次(图的广度优先遍历)】
Why is Prometheus a monitoring artifact sufficient to replace Zabbix?