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

做点心的网站外贸做什么产品出口好

做点心的网站,外贸做什么产品出口好,手机腾讯网,做网站备案必须是个人还是公司文章目录 unique_ptr所有权转移所有权释放make_unique 和直接(new)unique_ptr区别一 :需要一次性处理多个资源分配的地方make_unique比unique_ptr更安全区别二 :直接new支持自定义删除器 shared_ptrshared_ptr智能指针指向同一个对…

文章目录

  • unique_ptr
    • 所有权转移
    • 所有权释放
    • make_unique 和直接(new)unique_ptr
      • 区别一 :需要一次性处理多个资源分配的地方make_unique比unique_ptr更安全
      • 区别二 :直接new支持自定义删除器
  • shared_ptr
    • shared_ptr智能指针指向同一个对象的不同成员
    • 循环引用问题
    • 为什么weak_ptr能解决shared_ptr的循环引用问题
    • make_shared 和 直接 new 一个shared_ptr的区别
      • 区别一:make_shared资源分配更安全
      • 区别二:直接new支持自定义删除器
      • 区别三:内存分配方式不同
      • 为什么make_unique和直接new unique_ptr都是一次分配内存
      • shared_ptr合并分配的缺点
        • shared_ptr控制块内存的延迟释放是内存泄漏吗?

unique_ptr

所有权转移

unique_ptr不能被拷贝和用于赋值,因为unique_ptr删掉了这两个函数
在这里插入图片描述
但是底层源码重载了传右值的拷贝构造
所以可以通过std::move来通过转移所有权

unique_ptr<Data> p6(new Data());
//不可复制构造和赋值复制
//unique_ptr<Data>p7 = p6; 错误//p6释放所有权 转移到p7
unique_ptr<Data>p7 = move(p6);unique_ptr<Data>p8(new Data());
p7 = move(p8);//重新移动赋值,原有的p6会被释放掉
//重置空间,原空间清理
p7.reset(new Data());

所有权释放

注意!当unique_ptr释放所有权以后智能指针就不会再管理这块空间,需要自己手动释放空间!

//释放所有权
unique_ptr<Data>p9(new Data());
auto ptr9 = p9.release();//注意,release释放所有权以后要自己清理空间
delete ptr9;//!!!!!!

make_unique 和直接(new)unique_ptr

区别一 :需要一次性处理多个资源分配的地方make_unique比unique_ptr更安全

void process_data(std::unique_ptr<Data> p1, std::unique_ptr<Data> p2
);process_data(std::unique_ptr<Data>(new Data("A")),  // 分配资源 Astd::unique_ptr<Data>(new Data("B"))   // 分配资源 B
);

编译器在构造函数参数时,​执行顺序是不确定的。可能的执行顺序例如:

  1. new Data(“A”) → 成功,得到一个裸指针 A
  2. new Data(“B”) → 成功,得到一个裸指针 B*
  3. 构造unique_ptr 接管 A*
  4. 构造 unique_ptr 接管 B*

如果中间发生异常:

  1. new Data(“A”) → 成功,得到 A*
  2. new Data(“B”) → ​抛出异常(例如内存不足)​ ​此时 A* 尚未被 unique_ptr 接管!​ 异常被抛出后,裸指针 A* 无法被自动释放 → ​内存泄漏。

如果选用make_unique

process_data(std::make_unique<Data>("A"),  // 直接构造并接管资源 Astd::make_unique<Data>("B")   // 直接构造并接管资源 B
);

此时每一步的执行:

  1. make_unique(“A”) → ​立即构造对象并封装到 unique_ptr,无裸指针暴露
  2. make_unique(“B”) → 同上 如果 make_unique(“B”) 抛出异常:
    make_unique(“A”) 已经返回的 unique_ptr 会正常析构 → 资源 A 被自动释放没有泄漏!

区别二 :直接new支持自定义删除器

new支持在构造 unique_ptr 时指定自定义删除器

std::unique_ptr<MyClass, Deleter> p(new MyClass, custom_deleter);

但是make_unique不支持,只能使用默认的 delete 操作符。

shared_ptr

shared_ptr智能指针指向同一个对象的不同成员

sc2和sc3 分别 指向sc1的index1成员和index2成员,使sc1的引用计数+2

class Data
{
public:Data() {cout<< "Begin Data" << endl;}~Data() { cout<< "End Data" << endl; }int index1 = 0;int index2 = 0;
};{shared_ptr<Data>sc1(new Data);//打印引用计数 = 1cout << "sc1.use_count() = " << sc1.use_count() << endl;shared_ptr<int>sc2(sc1,&sc1->index1);//引用计数+1shared_ptr<int>sc3(sc1, &sc1->index2);//引用计数+1//打印引用计数 = 3cout << "sc1.use_count() = " << sc1.use_count() << endl;
}

在这里插入图片描述

循环引用问题

当两个或多个对象通过 shared_ptr ​互相持有对方时,它们的引用计数永远不会归零,导致内存无法释放。

	class A{public:A() { cout << "Create A" << endl; }~A() { cout << " Drop A " << endl; }void Do(){cout << "Do b2.use_count() = " << b2.use_count() << endl;auto b = b2.lock(); //复制一个shared_ptr 引用计数加一cout << "Do b2.use_count() = " << b2.use_count() << endl;}shared_ptr<B> b1;//强智能指针weak_ptr<B> b2;  //弱智能指针};class B{public:B() { cout << "Create B" << endl; }~B(){ cout << " Drop B " << endl; }shared_ptr<A> a1;//强智能指针weak_ptr<A> a2;  //弱智能指针};{auto a = make_shared<A>();//a引用计数+1auto b = make_shared<B>();//b引用计数+1a->b1 = b;//b引用计数+1//出作用域前,引用计数为2cout << "a->b1 = b;b.use_count()=" << b.use_count() << endl;b->a1 = a;//a引用计数+1//出作用域前,引用计数为2cout << "b->a1 = a;a.use_count()=" << a.use_count() << endl;}

由于调用问题,导致出作用域以后a和b的引用计数都还是1,所以空间没有被释放

在这里插入图片描述

改成使用weak_ptr

	{auto a = make_shared<A>();auto b = make_shared<B>();a->b2 = b;//weak_ptr 引用计数不加一a->Do();//Do函数里引用计数加一,出Do函数作用域减一cout << "a->b2 = b;b.use_count()=" << b.use_count() << endl;b->a2 = a;//引用计数不加一cout << "b->a2 = a;a.use_count()=" << a.use_count() << endl;}//不会产生循环引用问题

为什么weak_ptr能解决shared_ptr的循环引用问题

weak_ptr 本身不拥有资源所有权
它只是观察 shared_ptr 管理的对象,不会增加引用计数。

所以a->b2 = b;这句不会增加b的引用计数
同理b->a2 = a;这句也不会增加a的引用计数

但是由于weak_ptr只是一个观察者,无法访问任何资源,仅“观察”资源,不拥有所有权如果想要访问资源该怎么办呢?

如同a->Do();里做的那样
只要原 shared_ptr(即 a)未释放资源,就可以通过 lock() 获取有效的 shared_ptr 并访问。

void Do()
{cout << "Do b2.use_count() = " << b2.use_count() << endl;auto b = b2.lock(); //返回一个shared_ptr 引用计数加一//这里还可以做其他的访问shared_ptr资源的操作cout << "Do b2.use_count() = " << b2.use_count() << endl;}//出作用域加上的那个引用计数自动-1

通过weak_ptr.lock()返回 一个 shared_ptr 并将引用计数加一

(注意!只有当原shared_ptr对象还存在的时候才会返回shared_ptr,否者返回nullptr)

除了放函数里,还能放判断条件里

    if (auto a_shared = b->a_weak.lock()) {// 返回nullptr 说明shared_ptr被释放//不会执行此处} else {//引用计数+1std::cout << "A is already destroyed!" << std::endl;  // 输出此句}//引用计数-1

通过这种方式,weak_ptr 可以安全地观察资源,而不会导致循环引用或内存泄漏

make_shared 和 直接 new 一个shared_ptr的区别

区别一:make_shared资源分配更安全

原因和make_unique一样,这里就不再赘述了

区别二:直接new支持自定义删除器

区别三:内存分配方式不同

由于shared_ptr除了维护对象本身的内存以外还要维护一个控制块

  • ​强引用计数​(use_count):记录有多少个 shared_ptr 共享对象
  • ​弱引用计数​(weak_count):记录有多少个weak_ptr 观察对象
  • 自定义删除器​(如果存在)。 ​
  • 对象指针​(指向实际分配的对象)。

make_shared 在底层会 ​一次性分配一块连续内存,既存储对象本身,也存储控制块。

但是new shared_ptr会有两次分配

std::shared_ptr<MyClass> p(new MyClass);
  1. 第一次分配:new MyClass 分配对象内存。
  2. ​第二次分配:shared_ptr 构造函数内部为控制块分配内存。

为什么make_unique和直接new unique_ptr都是一次分配内存

因为unique_ptr 不需要维护引用计数,因此 ​没有控制块。无论通过 make_unique 还是直接 new,都只需分配对象内存

shared_ptr合并分配的缺点

对象和控制块内存绑定,即使所有 shared_ptr 销毁,若仍有 weak_ptr 存在,对象内存仍然需等待控制块释放(但析构函数会被及时调用)

shared_ptr控制块内存的延迟释放是内存泄漏吗?

由于make_shared 是一次性分配一块连续内存,同时存储 ​对象实例 和 ​控制块​(包含引用计数、弱引用计数等)

所以当没有weak_ptr存在时

通过make_shared建立的shared_ptr:

  • 对象析构函数立即被调用。
  • 整块内存(对象 + 控制块)立即释放。

通过new建立的shared_ptr:

  • 对象内存立即释放。
  • 控制块内存也立即释放。

当有weak_ptr存在时

通过make_shared建立的shared_ptr:

  • 对象析构函数被调用(资源清理)。 ​
  • 对象内存和控制块内存暂时保留​(直到所有 weak_ptr 也被销毁)。

通过new建立的shared_ptr:

  • 对象内存立即释放(仅保留控制块内存)。

由于make_shared对象和控制块内存是连续的,无法单独释放对象内存。所以必须等待所有 weak_ptr 销毁后,​整块内存才能一起释放。

那这是内存泄漏吗?

不是!​ 内存泄漏的定义是:​无法再访问且未释放的内存。
而在此时:
对象析构函数已被调用(资源已清理)。
内存仍被 weak_ptr 的控制块管理,虽然未释放,但程序仍能通过 weak_ptr 的机制感知到内存状态。
当所有 weak_ptr 销毁后,内存会被正确释放。

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

相关文章:

  • 汝州市住房和城乡建设局网站永久链接生成器
  • 百度地图 企业网站郑州网站建设的软件
  • 网站备案要幕布做网站网站是什么案件
  • 网站后台管理系统如何安装婚纱销售网站
  • 淮阳城乡建设局网站网站免费推广大全
  • 校园网站建设的意见与建议wordpress模板层级
  • 漳州市建设局网站做的门户网站怎么绑定ip地址
  • 设计网站的公司wordpress 建论坛
  • 生鲜网站建设php旅游类网站开发
  • 吉安建设工程项目网站谁做的怀来吧网站
  • 模板网站怎么做卖大学生网站制作作业免费下载
  • 哪个网站可以悬赏做图有没有医学生做课件的网站
  • 湛江专业建网站哪家好买链接做网站 利润高吗
  • asp网站后台安全退出网站开发如何避开法律
  • 服务器与网站吗DW做网站下拉列表怎么做
  • php网站跟随导航wordpress excerpt
  • 网络营销怎么做网站广州网站建设服务商
  • 静态网站做一单多少钱视频制作的基本流程是什么
  • 网站开发设计需要什么证书宁波模板建站定制
  • 有做销售产品的网站wordpress视频弹窗
  • 三明建设网站网站的竞价怎么做
  • 潘家园做网站的公司360商城官网
  • 如何批量建网站石家庄专业网站设计
  • 河南网站seo设计百度做的网站 后台管理怎么进入
  • 做淘客需要用的网站c2c平台盈利模式有哪些
  • 台州椒江找人做网站重庆网站建设外包公司
  • 下载专门做初中数学题的网站广安建设企业网站
  • 济南市建设局网站网站开发中涉及的侵权行为
  • 虚拟交易网站开发网络游戏下载平台
  • 山东网站优化推广天津百度推广公司