当前位置: 首页 > wzjs >正文

wordpress插件 缩略图深圳网站建设优化

wordpress插件 缩略图,深圳网站建设优化,做图库网站用什么系统软件,wordpress换模版【c】【智能指针】shared_ptr底层实现 智能指针之前已经写过了,但是考虑到不够深入,应该再分篇写写。 1 shared_ptr 1.1 shared_ptr 是什么 std::shared_ptr是一个类模板,它的对象行为像指针,但是它还能记录有多少个对象共享它…

【c++】【智能指针】shared_ptr底层实现

智能指针之前已经写过了,但是考虑到不够深入,应该再分篇写写。

1 shared_ptr

1.1 shared_ptr 是什么

std::shared_ptr是一个类模板,它的对象行为像指针,但是它还能记录有多少个对象共享它管理的内存对象
多个std::shared_ptr可以共享同一个对象
最后一个std::shared_ptr被销毁时,它会自动释放它所指向的对象


1.2 shared_ptr创建和销毁

可以通过make_shared<>函数来创建。
可以通过拷贝或赋值另一个shared_ptr来创建
eg:sp1和sp2指向同一个对象,内存对象的引用计数为2。当sp1被销毁时,引用计数减为1,sp2仍然指向该对象。当sp2被销毁时,引用计数减为0,内存对象被销毁。
在这里插入图片描述


1.3 shared_ptr的底层原理

element_type*    _M_ptr;         // 所管理对象的地址.
__shared_count<_Lp>  _M_refcount;    // 引用计数块地址.

在这里插入图片描述
std::shared_ptr在内部其只有两个指针成员:

  • 一个指针是所管理的数据的地址
  • 一个指针是控制块的地址
    包括引用计数
    weak_ptr计数
    删除器(Deleter)
    分配器(Allocator)

因为不同shared_ptr指针需要共享相同的内存对象,因此引用计数的存储是在 上的。
而unique_ptr只有一个指针成员,指向所管理的数据的地址。因此一个shared_ptr对象的大小是它大小的倍。
eg:vs2022-64下:

int main()
{std::cout << sizeof(std::shared_ptr<int>) << std::endl; // 8std::cout << sizeof(std::unique_ptr<int>) << std::endl; // 4
}

在这里插入图片描述


1.4 std::shared_ptr的简单实现

我们通过下面这个简单的类来模拟std::shared_ptr<>的实现,来理解引用计数的实现原理。
这里我们为了简单,只实现了

  • shared_ptr的拷贝构造函数析构函数赋值运算符函数引用计数只是简单地用了一个int类型的内存空间
  • 省略了weak_ptr的计数、删除器和分配器,不考虑多线程的情况。
  • 当我们销毁一个shared_ptr时,引用计数减1。当引用计数减为0时,我们删除指向实际数据的指针和指向引用计数的指针。
  • 当我们拷贝一个shared_ptr时,引用计数加1。
  • 当我们赋值一个shared_ptr时,我们首先递减左侧运算对象的引用计数。如果引用计数变为0,我们就释放左侧运算对象分配的内存以及引用计数的内存。然后拷贝右侧运算对象的数据指针和引用计数指针,最后递增引用计数。
template<typename T>
class shared_ptr {
public:// 构造函数  // 初始化智能指针,传入一个裸指针(默认为 nullptr)  shared_ptr(T* ptr = nullptr) : m_ptr(ptr), m_refCount(new int(1)) {}// 拷贝构造函数  // 通过另一个 shared_ptr 构造,增加引用计数  shared_ptr(const shared_ptr& other) : m_ptr(other.m_ptr), m_refCount(other.m_refCount) {// 增加引用计数  (*m_refCount)++;}// 析构函数  ~shared_ptr() {// 减少引用计数  (*m_refCount)--;// 如果引用计数为 0,释放内存  if (*m_refCount == 0) {delete m_ptr;delete m_refCount;}}// 重载赋值运算符  shared_ptr& operator=(const shared_ptr& other) {// 检查自我赋值  if (this != &other) {// 减少旧对象的引用计数  (*m_refCount)--;// 如果引用计数为 0,释放内存  if (*m_refCount == 0) {delete m_ptr;delete m_refCount;}// 复制新对象的数据和引用计数指针,并增加引用计数  m_ptr = other.m_ptr;m_refCount = other.m_refCount;// 增加引用计数  (*m_refCount)++;}return *this;}private:T* m_ptr;            // 指向实际数据的指针  int* m_refCount;     // 引用计数  
};

ps:多线程时 引用计数的++操作需要是原子性的。考虑使用std::atomic

  • 是 C++11 引入的模板类,位于头文件 中,主要用于在多线程环境下实现原子操作,从而避免数据竞争(data race),保证线程安全。

1.5 什么时候用 std::shared_ptr<T>

std::shared_ptr<T> 主要用于以下场景:
1. 资源创建昂贵、比较耗时的场景

  • 创建对象代价很高(例如文件、网络、数据库等),不希望频繁创建和销毁。
  • 通过共享指针来管理对象生命周期,避免频繁创建和释放导致的性能损耗。

示例:管理数据库连接

#include <iostream>
#include <memory>class Database {
public:Database() { std::cout << "Connecting to Database\n"; }~Database() { std::cout << "Closing Database Connection\n"; }
};void useDatabase(std::shared_ptr<Database> db) {std::cout << "Using Database\n";
}int main() {auto db = std::make_shared<Database>(); // 资源创建昂贵,使用共享指针管理useDatabase(db); // 共享所有权
}

在这个例子中,Database连接创建和释放都很昂贵,使用 shared_ptr 可以在多个对象间安全地共享连接(并非多线程),等所有使用者都释放之后才会关闭连接。

  • std::shared_ptr` 的引用计数是线程安全的(即对引用计数的增加和减少是原子操作,不会导致竞争条件)
  • 对实际管理的对象的操作是非线程安全的
    ps: 之前的文章有提到

在示例中,以下部分是线程安全的:

  • 引用计数的增加和减少
  • 判断对象是否需要释放
  • 只读访问是线程安全的

需要加锁的部分:

  • 对实际对象(Database)的数据修改需要加锁。
    如果多个线程同时修改 Database 对象的内容,可能会发生数据竞争,导致未定义行为。因此,需要在访问或修改对象时加锁

2. 需要共享资源的所有权

  • 一个对象的生命周期可能同时涉及多个对象,但不清楚谁会最终释放这个对象。
  • std::shared_ptr 使用引用计数,确保在最后一个 shared_ptr 离开作用域时才释放资源。

示例:对象被多个对象共享

#include <iostream>
#include <memory>class A {
public:A() { std::cout << "A constructed\n"; }~A() { std::cout << "A destroyed\n"; }
};int main() {std::shared_ptr<A> sp1 = std::make_shared<A>();std::shared_ptr<A> sp2 = sp1; // 引用计数 +1std::shared_ptr<A> sp3 = sp2; // 引用计数 +1std::cout << "Use count: " << sp1.use_count() << "\n"; // 输出 3sp2.reset(); // 引用计数 -1std::cout << "Use count after sp2 reset: " << sp1.use_count() << "\n"; // 输出 2sp1.reset(); // 引用计数 -1std::cout << "Use count after sp1 reset: " << sp3.use_count() << "\n"; // 输出 1sp3.reset(); // 最终释放对象
}
  • sp1, sp2, sp3 共享对 A 对象的所有权。
  • 只有最后一个 shared_ptr 释放时,才会析构 A 对象。

不适用 shared_ptr的情况
1. 存在明显的所有者 → 使用 unique_ptr 更合适。
2. 不需要共享所有权 → 使用裸指针或 unique_ptr
3. 循环引用问题 → 使用 weak_ptr 解决。

部分转自:https://zhuanlan.zhihu.com/p/672745555?utm_source=chatgpt.com

http://www.dtcms.com/wzjs/500610.html

相关文章:

  • 樱桃企业网站管理系统v1.1-cms网站设计框架
  • 光谷做网站推广价格快速排名推荐
  • 广州牌手表网站经典营销案例100例
  • 萝岗手机网站建设长沙百度搜索排名
  • 企业网站建设方案详细方案华与华营销策划公司
  • 在线考试网站开发报价友情链接怎么交换
  • 济南网站建设方案书范文百度图片搜索网页版
  • 网站建设属于什么支出关键词歌词
  • 做营销网站企业优化关键词的方法包括
  • 手机如何自制网站网络营销方式包括哪些
  • 新网站 蜘蛛楼市最新消息
  • 新手做网站如何赚钱网站制作教程
  • 中山精品网站建设流程千万别手贱在百度上搜这些词
  • 资讯类网站模板在线客服系统
  • 茂名整站优化网页制作app
  • 法治建设的网站站长工具seo推广
  • 开家网站建设培训学校项目推广平台有哪些
  • erp软件前十名seo网站优化培训多少价格
  • 郑州做网站的联系方式网络营销与策划试题及答案
  • 苹果cms影视源码武汉抖音seo搜索
  • 昌平做网站公司搜索引擎营销的英文缩写
  • 永久建站空间购买网络推广是什么专业
  • 黄石网站建设公司盐城seo排名
  • 做效果图比较好的模型网站有哪些营销推广策划方案
  • 接做施工图的网站免费推广方式都有哪些
  • 广东平台网站建设制作正规推广赚佣金的平台
  • thinkphp制作网站开发成都网站推广公司
  • 哪些网站是做色选机销售的网络营销的功能有哪些?
  • wordpress怎么恢复自带主题seo基础知识
  • 做淘宝网站用什么软件做湖南网络优化