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

想自己做衣服上哪个网站学淘宝seo是什么意思

想自己做衣服上哪个网站学,淘宝seo是什么意思,网站关键词怎么做可以排名,网站站点风格序言 在使用 C / C 进行编程时,许多场景都需要我们在堆上申请空间,堆内存的申请和释放都需要我们自己进行手动管理。这就存在容易造成堆内存泄露(忘记释放),二次释放,程序发生异常时内存泄露等问题&#xf…

序言

 在使用 C / C++ 进行编程时,许多场景都需要我们在堆上申请空间,堆内存的申请和释放都需要我们自己进行手动管理。这就存在容易造成堆内存泄露(忘记释放),二次释放,程序发生异常时内存泄露等问题,这对长期运行的程序来说是致命的!
 但在 C++11 中引入了智能指针,使我们将内存的管理交给智能指针。


1. 什么是智能指针

1.1 概念

 该指针旨在自动管理动态分配的内存,减少内存泄漏和野指针的问题。智能指针是模板类,它们的行为类似于指针,但提供了自动的内存管理功能

1.2 RAII 思想

 智能指针在 C++ 中主要使用了 资源获取即初始化(Resource Acquisition Is Initialization, RAII) 的思想,以及所有权管理的概念。RAII 的核心思想是,资源的分配(获取)和初始化发生在对象的构造期间,而 资源的释放(清理)则发生在对象的析构期间。这种方式通过对象的生命周期来自动管理资源,避免了忘记释放资源(如内存泄漏)的问题。

1.3 体现 RAII 思想

 在这里为大家举一个简单的例子来体现 RAII 思想

这是我们现在的内存管理,我们需要手动释放申请的资源:

int main()
{int* Ptr = new int[5];// Do Otherthing......delete[] Ptr;return 0;
}

现在实现一个简单的智能指针:

template <class T>
class SmartPtr
{
public:SmartPtr(T* Ptr):_Ptr(Ptr){}// Ohther Functions... ~SmartPtr(){std::cout << "Delete Ptr" << std::endl;delete _Ptr;}private:T* _Ptr;
};int main()
{SmartPtr<int> sp(new int(1));return 0;
}

我们将申请的资源交给智能指针为我们管理,当程序结束时,将自动执行析构函数释放资源:
在这里插入图片描述


2. 三种主要的智能指针

2.1 unique_ptr

unique_ptr 是一种 独占所有权 的智能指针,意味着 同一时间内只能有一个 unique_ptr 指向给定的对象,他直接删除了他的拷贝构造和赋值运算符重载:
在这里插入图片描述在这里插入图片描述
注意:保留了对将亡值的赋值运算符重载,因为就修改操作后将亡值就释放了,依旧满足独占所有权的特性!

简单使用一下该指针:

void Ptr_1()
{std::unique_ptr<MyClass> up1(new MyClass); up1->DoSomething();std::unique_ptr<MyClass> up2(move(up1)); // 移动构造std::cout << up1 << std::endl; // up1 这时已被悬空
}

程序输出结果:

I am working!
0000000000000000
~MyClass()

 该智能指针还是比较简单的,但是一定要注意指针被悬空后的情况!

2.2 shared_ptr

shared_ptr 是一种 共享所有权 的智能指针,允许多个 shared_ptr 实例指向同一个对象。每个 shared_ptr 都有一个与之关联的计数器,称为控制块,用于跟踪有多少个 shared_ptr 实例指向该对象。当最后一个指向对象的 shared_ptr 被销毁或重置时,对象才会被删除。

简单使用一下该指针:

void Ptr_2()
{std::shared_ptr<MyClass> sp1(new MyClass); // 构造 std::shared_ptr<MyClass> sp2(sp1); // 拷贝构造sp2->DoSomething();std::cout << "The use counts = " << sp1.use_count() << std::endl; // 查看计数器
}

程序输出结果:

I am working!
The use counts = 2
~MyClass()


循环引用问题

 使用该指针需要注意一个非常特殊的情况,一不小心掉入坑中!这种情况就是循环引用:

struct Node
{Node(int val):_val(val),_next(nullptr),_prev(nullptr){}~Node(){std::cout << "~Node()" << std::endl;} int _val;std::shared_ptr<Node> _prev;std::shared_ptr<Node> _next;
};void Ptr_3()
{std::shared_ptr<Node> sp1(new Node(1));std::shared_ptr<Node> sp2(new Node(2));// 相互指向sp1->_next = sp2;sp1->_prev = sp1;
}

运行程序,我们会发现并没有正常的未释放资源!出现问题的原因,用图来表示:
在这里插入图片描述
当我们函数结束时,函数栈帧销毁,这时两个指针对象调用析构函数来释放资源:
在这里插入图片描述
这里的析构函数并不会真正意义上调用 delete ,而是减少引用!直到引用计数为 0 才会调用 delete,所以,这里的资源并没有真正的被释放,因为 next,prev 指针的存在,所以资源并不会被释放!

2.3 weak_ptr

weak_ptr 是一种 不拥有其所指向对象的智能指针,它主要 用于解决 shared_ptr 之间的循环引用问题weak_ptr 必须与 shared_ptr 一起使用,因为它不拥有对象,所以不会增加对象的共享计数。
 简单使用一下该指针:

void Ptr_4()
{// std::weak_ptr<int> wp(new int(1)); // 错误的使用方法 weak_ptr 不能直接管理对象的生命周期std::shared_ptr<int> sp(new int(1));std::weak_ptr<int> wp(sp);std::cout << wp.use_count() << std::endl; 
}

现在我们使用 weak_ptr 来解决循环引用的问题:

struct Node
{Node(int val):_val(val){}~Node(){std::cout << "~Node()" << std::endl;} int _val;std::weak_ptr<Node> _prev;std::weak_ptr<Node> _next;
};void Ptr_3()
{std::shared_ptr<Node> sp1(new Node(1));std::shared_ptr<Node> sp2(new Node(2));// 相互指向sp1->_next = sp2;sp2->_prev = sp1;
}

_prev, _next 修改为 weak_ptr 来代表不进行引用计数的增加,只是简单的指向,资源现在被正常的释放!

2.4 自定义删除器

 在智能指针的底层,对于资源的释放,单个就使用 delete,数组就是使用 delete[] ,大绝大多数场景下都是没问题的。但是,总是有特殊情况:

void Ptr_5()
{std::shared_ptr<FILE> sp(fopen("test.txt", "w"));
}

请问,这个使用 delete 可以删除吗?当然是不可以,有人会觉得,这不是在鸡蛋里挑骨头吗?其实,我们很多时候就是更应该想到极端情况,Bug 不能被消除,但可以被极力避免!我们程序的健壮性,肯定决定了我们运行的稳定性!

 这时,我们就可以使用自定义删除器:
在这里插入图片描述
我们需要传递一个可调用对象告诉他,该怎么删除。选择很多,包括函数指针,仿函数… 在这里我们选择 lambda ,这就非常的方便!

std::shared_ptr<FILE> sp(fopen("test.txt", "w"), [](FILE* file) {fclose(file); });

3. 简单实现

 在这里我们简单实现一个 shared_ptr

3.1 构造函数

 首先,先介绍三个成员变量:

T* _Ptr;
std::atomic<int>* _RefCounts; // 引用计数(保证原子性)
std::function<void(T*)> _Del; // 自定义删除器
  • _Ptr:是我们需要管理的资源
  • _RefCounts:计数器,记录多少指针指向该资源(本质就是 int,但是支持原子性操作)
  • _Del:删除器,保证资源正常的释放,有特殊删除需求可传入

一共实现了简单的三个构造函数:

// 构造函数(默认删除器)
SharedPtr(T* Ptr): _Ptr(Ptr), _RefCounts(new std::atomic<int>(1)), _Del([](T* val) { delete val; })
{}// 构造函数(自定义删除器)
template<class D>
SharedPtr(T* Ptr, D Del): _Ptr(Ptr), _RefCounts(new std::atomic<int>(1)), _Del(Del)
{}// 拷贝构造
SharedPtr(const SharedPtr<T>& sp): _Ptr(sp._Ptr), _RefCounts(sp._RefCounts), _Del(sp._Del)
{++(*_RefCounts);
}

3.2 析构函数

 该函数在释放资源前需要判断,当引用计数为 0 时才可释放资源,避免正在使用的指针被悬空:

// 当计数置 0 时调用
void destructor()
{_Del(_Ptr);_Ptr = nullptr;delete _RefCounts;_RefCounts = nullptr;
}// 析构函数
~SharedPtr()
{// 引用减少--(*_RefCounts);if (*_RefCounts == 0){destructor();}
}

3.3 赋值运算符重载

 赋值运算符重载需要极其注意,在指向其他资源前需要对当前资源释放(引用计数减一,若为 0,才真正释放资源):

void clear()
{// 引用减少--(*_RefCounts);if (*_RefCounts == 0){destructor();}
}SharedPtr<T>& operator=(const SharedPtr<T>& sp)
{if (this != &sp) // 防止自我赋值{clear(); // 释放当前资源_Ptr = sp._Ptr;_RefCounts = sp._RefCounts;_Del = sp._Del; // 复制删除器++(*_RefCounts);}return *this;
}

3.4 其余的运算符重载

 此部分为常用的运算符重载:

T& operator* ()
{return *_Ptr;
}T* operator->()
{return _Ptr;
}

4. 总结

 在这篇文章中我们首先介绍了智能指针的思想,之后分别介绍了常用的三种智能指针(unique_ptr, shared_ptr, weak_ptr),最后我们简单的实现了第二个指针,希望大家有所收获!


文章转载自:
http://dinncovestock.knnc.cn
http://dinncoundergo.knnc.cn
http://dinncosendout.knnc.cn
http://dinncochemoreception.knnc.cn
http://dinncocommunity.knnc.cn
http://dinncowhinsill.knnc.cn
http://dinncopore.knnc.cn
http://dinncodromomania.knnc.cn
http://dinncoscrubber.knnc.cn
http://dinncoendive.knnc.cn
http://dinncoradioscopy.knnc.cn
http://dinncopaleobiology.knnc.cn
http://dinncocpsc.knnc.cn
http://dinnconoma.knnc.cn
http://dinncopatois.knnc.cn
http://dinncopentad.knnc.cn
http://dinncoidahoan.knnc.cn
http://dinncoinconnected.knnc.cn
http://dinncovas.knnc.cn
http://dinncodumps.knnc.cn
http://dinncodisconsolate.knnc.cn
http://dinncoobtect.knnc.cn
http://dinncophantast.knnc.cn
http://dinncoperdie.knnc.cn
http://dinncomaidhood.knnc.cn
http://dinncostalker.knnc.cn
http://dinncobiparietal.knnc.cn
http://dinncohaka.knnc.cn
http://dinncosecretary.knnc.cn
http://dinncoitalicise.knnc.cn
http://dinncocallisthenics.knnc.cn
http://dinncothat.knnc.cn
http://dinncoyoungling.knnc.cn
http://dinncocursillo.knnc.cn
http://dinncozincification.knnc.cn
http://dinncocommutator.knnc.cn
http://dinnconocturnality.knnc.cn
http://dinncofactually.knnc.cn
http://dinncobartlett.knnc.cn
http://dinncocopepod.knnc.cn
http://dinncoringling.knnc.cn
http://dinncosmelting.knnc.cn
http://dinncoporous.knnc.cn
http://dinncobatwoman.knnc.cn
http://dinncoenactment.knnc.cn
http://dinncokhapra.knnc.cn
http://dinncodocete.knnc.cn
http://dinncokirghiz.knnc.cn
http://dinncoaffettuoso.knnc.cn
http://dinncovesica.knnc.cn
http://dinncoshoreless.knnc.cn
http://dinncoqstol.knnc.cn
http://dinncosubroutine.knnc.cn
http://dinncochoreal.knnc.cn
http://dinncocoterminal.knnc.cn
http://dinncocontracture.knnc.cn
http://dinncothermophil.knnc.cn
http://dinncooutlandish.knnc.cn
http://dinncowirily.knnc.cn
http://dinncoviyella.knnc.cn
http://dinncoquayage.knnc.cn
http://dinncorealisation.knnc.cn
http://dinncoleucocyte.knnc.cn
http://dinncosheva.knnc.cn
http://dinncoconnotate.knnc.cn
http://dinncoshelterless.knnc.cn
http://dinncoradiogenetics.knnc.cn
http://dinncogrounding.knnc.cn
http://dinncocoldish.knnc.cn
http://dinncorotc.knnc.cn
http://dinncorelucent.knnc.cn
http://dinncoradionuclide.knnc.cn
http://dinncowolverene.knnc.cn
http://dinncowolfishly.knnc.cn
http://dinncodoest.knnc.cn
http://dinncoiranian.knnc.cn
http://dinncoyestereven.knnc.cn
http://dinncocella.knnc.cn
http://dinncotrimethylamine.knnc.cn
http://dinncoambiance.knnc.cn
http://dinncowhifflow.knnc.cn
http://dinncodia.knnc.cn
http://dinncosacculate.knnc.cn
http://dinncogut.knnc.cn
http://dinncotourniquet.knnc.cn
http://dinncoaufwuch.knnc.cn
http://dinncolgm.knnc.cn
http://dinncogarn.knnc.cn
http://dinncomonospermous.knnc.cn
http://dinncosquirrel.knnc.cn
http://dinncofascine.knnc.cn
http://dinncointerconceptional.knnc.cn
http://dinncoheronry.knnc.cn
http://dinncocamoufleur.knnc.cn
http://dinncocontubernal.knnc.cn
http://dinncocrescive.knnc.cn
http://dinncodisentail.knnc.cn
http://dinncounamo.knnc.cn
http://dinncohullo.knnc.cn
http://dinncounsurveyed.knnc.cn
http://www.dinnco.com/news/122631.html

相关文章:

  • 做搜狗网站点击电商网站规划
  • 30几岁的人想学做网站免费获客平台
  • 怎么在建筑网站做翻译兼职外贸推广建站
  • 动态网站静态发布世界500强企业排名
  • 免费建站的网上如何做广告
  • 域名还没备案可以做网站吗廊坊seo优化排名
  • 做最好言情网站网站seo推广员招聘
  • 网站 网站建设定制网站建设的方法有哪些
  • wordpress分类不显示文章网站优化网站优化
  • 怎样做美瞳代购网站谷歌搜索引擎香港入口
  • 驻马店做网站公司广州企业网站建设
  • 在线购物网站 项目360搜索推广
  • 成都网站建设 3eseo关键词排名技巧
  • .net开发微信网站流程sem投放是什么意思
  • 大连地区网站建设seo关键词排名优化是什么
  • 中国有没有一家做茶叶的网站青岛关键词搜索排名
  • 网站开发方法是什么网站策划运营
  • 建网站用什么服务器系统优化app
  • 广州网站建设制作武汉网络广告推广服务
  • vs2010做网站时间控件yandx引擎入口
  • 试述网站建设的步骤南宁网站建设及推广
  • 工业产品设计作品seo管理
  • 衡水医院网站建设互联网广告代理加盟
  • 什么网站不能备案百度站长工具添加不了站点
  • 做网站需要公司授权嘛百度关键词优化多久上首页
  • 可以做外链的音乐网站企业推广是什么意思
  • 做采集网站难不做网站用什么编程软件
  • 进口食品销售销售在那个网站做企业网站制作步骤
  • 做外贸没有企业网站谷歌地图下载
  • 浏览器网站大全网站空间