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

wordpress 插入表格成都公司网站seo

wordpress 插入表格,成都公司网站seo,qiao.baidu.com,青岛模板建站多少钱文章目录 1.为什么需要智能指针?2.智能指针原理2.1 RAll2.2 像指针一样使用 3.C11的智能指针3.1 auto_ptr3.2 unique_ptr3.3 shared_ptr3.4 weak_ptr 4.删除器希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力! 智能指针是 C 中用于自动…

文章目录

  • 1.为什么需要智能指针?
  • 2.智能指针原理
    • 2.1 RAll
    • 2.2 像指针一样使用
  • 3.C++11的智能指针
    • 3.1 auto_ptr
    • 3.2 unique_ptr
    • 3.3 shared_ptr
    • 3.4 weak_ptr
  • 4.删除器
  • 希望读者们多多三连支持
  • 小编会继续更新
  • 你们的鼓励就是我前进的动力!

智能指针是 C++ 中用于自动管理动态内存的类模板,它通过 RAII(资源获取即初始化)技术避免手动 new / delete 操作,从而显著减少内存泄漏和悬空指针的风险

1.为什么需要智能指针?

int div()
{int a, b;cin >> a >> b;if (b == 0)throw invalid_argument("除0错误");return a / b;
}void Func()
{int* p1 = new int;int* p2 = new int;cout << div() << endl;delete p1;delete p2;
}int main()
{try{Func();}catch (exception& e){cout << e.what() << endl;}return 0;
}

如果 p1 这里 new 抛异常会如何?

p1 未成功分配,值为 nullptr
函数直接跳转到 catch 块,p2 未分配,无内存泄漏

如果 p2 这里 new 抛异常会如何?

p1 已分配但未释放,导致内存泄漏
函数跳转到 catch 块,p2 未分配,delete p1delete p2 均未执行

如果 div 调用这里又会抛异常会如何?

p1p2 均已分配但未释放,导致双重内存泄漏
函数跳转到 catch 块,打印错误信息(如 “除 0 错误”)

C++ 不像 java 具有垃圾回收机制,能够自动回收开辟的空间,需要自行手动管理,但是自己管理有时又太麻烦了,况且这里只是两个指针就产生了这么多问题,因此在 C++11 就推出了智能指针用于自动管理内存

2.智能指针原理

2.1 RAll

template<class T>
class SmartPtr 
{
public:SmartPtr(T* ptr = nullptr): _ptr(ptr){}~SmartPtr(){if (_ptr)delete _ptr;}private:T* _ptr;
};int main()
{SmartPtr<int> sp1(new int(1));SmartPtr<string> sp2(new string("xxx"));return 0;
}

RAIIResource Acquisition Is Initialization)是一种利用对象生命周期来控制程序资源(如内存、文件句柄、网络连接、互斥量等等)的简单技术

简单来说,就是把创建的对象给到 SmartPtr 类来管理,当对象的生命周期结束的时候,刚好类也会自动调用析构函数进行内存释放

这种做法有两大好处:

  • 不需要显式地释放资源
  • 采用这种方式,对象所需的资源在其生命期内始终保持有效

2.2 像指针一样使用

都叫做智能指针了,那肯定是可以当作指针一样使用了,指针可以解引用,也可
以通过 -> 去访问所指空间中的内容,因此类中还得需要将 *-> 重载下,才可让其像指针一样去使用

template<class T>
class SmartPtr
{
public:SmartPtr(T* ptr):_ptr(ptr){}~SmartPtr(){cout << "delete:" << _ptr << endl;delete _ptr;}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}
private:T* _ptr;
};

* 重载返回对象,-> 重载返回地址,这部分的知识点在迭代器底层分析已经讲过很多遍了,就不过多叙述了,可自行翻阅前文

3.C++11的智能指针

智能指针一般放在 <memery> 文件里,C++11 也参考了第三方库 boost

  1. C++ 98 中产生了第一个智能指针 auto_ptr
  2. C++ boost 给出了更实用的 scoped_ptrshared_ptrweak_ptr
  3. C++ TR1,引入了 shared_ptr 等。不过注意的是 TR1 并不是标准版
  4. C++ 11,引入了 unique_ptrshared_ptrweak_ptr。需要注意的是 unique_ptr对应 boostscoped_ptr。并且这些智能指针的实现原理是参考 boost 中的实现的

3.1 auto_ptr

template<class T>
class auto_ptr
{
public:// RAII// 像指针一样auto_ptr(T* ptr):_ptr(ptr){}~auto_ptr(){cout << "delete:" << _ptr << endl;delete _ptr;}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}// ap3(ap1)// 管理权转移auto_ptr(auto_ptr<T>& ap):_ptr(ap._ptr){ap._ptr = nullptr;}auto_ptr<T>& operator=(auto_ptr<T>& ap) {if (this != &ap) {_ptr = ap._ptr;       // 转移所有权ap._ptr = nullptr;    // 原指针置空}return *this;}
private:T* _ptr;
};

auto_ptrC++98 就已经被引入,实现了智能指针如上面所讲的最基础的功能,同时他还额外对拷贝构造、= 重载进行了显式调用,但是这种拷贝虽然能解决新对象的初始化,但是对于被拷贝的对象,造成了指针资源所有权被转移走,跟移动构造有些类似

因此,auto_ptr 会导致管理权转移,拷贝对象被悬空,auto_ptr 是一个失败设计,很多公司明确要求不能使用 auto_ptr

3.2 unique_ptr

template<class T>
class unique_ptr
{
public:// RAII// 像指针一样unique_ptr(T* ptr):_ptr(ptr){}~unique_ptr(){cout << "delete:" << _ptr << endl;delete _ptr;}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}// ap3(ap1)// 管理权转移// 防拷贝unique_ptr(unique_ptr<T>& ap) = delete;unique_ptr<T>& operator=(unique_ptr<T>& ap) = delete;
private:T* _ptr;
};

unique_ptr 很简单粗暴,直接禁止了拷贝机制

因此,建议在不需要拷贝的场景使用该智能指针

3.3 shared_ptr

template<class T>
class shared_ptr
{
public:// RAII// 像指针一样shared_ptr(T* ptr = nullptr):_ptr(ptr),_pcount(new int(1)){}~shared_ptr(){if (--(*_pcount) == 0){cout << "delete:" << _ptr << endl;delete _ptr;delete _pcount;}}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}// sp3(sp1)shared_ptr(const shared_ptr<T>& sp):_ptr(sp._ptr),_pcount(sp._pcount){++(*_pcount);}shared_ptr<T>& operator=(const shared_ptr<T>& sp){if (_ptr == sp._ptr)return *this;if (--(*_pcount) == 0){delete _ptr;delete _pcount;}_ptr = sp._ptr;_pcount = sp._pcount;++(*_pcount);return *this;}int use_count() const{return *_pcount;}T* get() const{return _ptr;}private:T* _ptr;int* _pcount;
};

C++11 中的智能指针就属 shared_ptr 使用的最多,因为它解决了赋值造成的资源被转移可能会被错误访问的问题

类中增加一个新的指针 _pcount 用于计数,即计数有多少个 _ptr 指向同一片空间,多个 shared_ptr 可以同时指向同一个对象,每次创建新的 shared_ptr 指向该对象,引用计数加 1;每次 shared_ptr 析构或者被赋值为指向其他对象,引用计数减 1。当最后一个指向该对象的 shared_ptr 析构时,对象会被自动删除,从而避免内存泄漏

🔥值得注意的是: shared_ptr 同时也支持了无法自己给自己赋值,这里还涉及一些关于线程安全的知识点,待 Linux 学习过后再来补充

3.4 weak_ptr

看似完美的 shared_ptr 其实也会有疏漏,比如:引用循环

struct ListNode
{int _data;shared_ptr<ListNode> _next;shared_ptr<ListNode> _prev;
};
int main()
{shared_ptr<ListNode> node1(new ListNode);shared_ptr<ListNode> node2(new ListNode);cout << node1.use_count() << endl;cout << node2.use_count() << endl;node1->_next = node2;node2->_prev = node1;cout << node1.use_count() << endl;cout << node2.use_count() << endl;return 0;
}

当执行 node1->next = node2node2->prev = node1 时,node1 内部的 _next 指针指向 node2node2 内部的 _prev 指针指向 node1 。这就导致两个节点之间形成了循环引用关系。此时,由于互相引用,每个节点的引用计数都变为 2 ,因为除了外部的智能指针引用,还多了来自另一个节点内部指针的引用

node1node2 智能指针对象离开作用域开始析构时,它们首先会将所指向节点的引用计数减 1 。此时,每个节点的引用计数变为 1 ,而不是预期的 0 。这是因为 node1_next 还指向 node2node2_prev 还指向 node1 ,使得它们的引用计数无法归零

对于 shared_ptr 来说,只有当引用计数变为 0 时才会释放所管理的资源。由于这种循环引用的存在,node1 等待 node2 先释放(因为 node2_prev 引用着 node1 ),而 node2 又等待 node1 先释放(因为 node1_next 引用着 node2 ),最终导致这两个节点所占用的资源都无法被释放,造成内存泄漏

class ListNode 
{
public:weak_ptr<ListNode> _next; weak_ptr<ListNode> _prev;
};

为了解决 shared_ptr 的循环引用问题,通常可以使用 weak_ptrweak_ptr 是一种弱引用智能指针,它不会增加所指向对象的引用计数。将循环引用中的某一个引用(比如 ListNode 类中的 _prev_next 其中之一)改为 weak_ptr 类型,就可以打破循环引用

因此,weak_ptr 是一种专门解决循环引用问题的指针

4.删除器

#include <iostream>
#include <memory>
#include <string>using namespace std;class A 
{
public:~A() { cout << "A::~A()" << endl; }
};// 仿函数删除器:用于释放malloc分配的内存
template<class T>
struct FreeFunc 
{void operator()(T* ptr) const {cout << "FreeFunc: free memory at " << ptr << endl;free(ptr);}
};// 仿函数删除器:用于释放数组
template<class T>
struct DeleteArrayFunc 
{void operator()(T* ptr) const {cout << "DeleteArrayFunc: delete[] memory at " << ptr << endl;delete[] ptr;}
};int main() 
{// 使用FreeFunc删除器的shared_ptrshared_ptr<int> sp1((int*)malloc(sizeof(int)), FreeFunc<int>());*sp1 = 100;cout << "sp1: " << *sp1 << " at " << sp1.get() << endl;// 离开作用域时调用FreeFunc删除器// 使用DeleteArrayFunc删除器的shared_ptrshared_ptr<int> sp2(new int[5], DeleteArrayFunc<int>());for (int i = 0; i < 5; ++i) {sp2.get()[i] = i;}cout << "sp2 array:";for (int i = 0; i < 5; ++i) {cout << " " << sp2.get()[i];}cout << endl;// 离开作用域时调用DeleteArrayFunc删除器// 使用lambda删除器管理A对象数组shared_ptr<A> sp4(new A[3], [](A* p) {cout << "Lambda: deleting array at " << p << endl;delete[] p;});cout << "sp4 array of A objects created" << endl;// 离开作用域时调用lambda删除器// 使用lambda删除器管理文件句柄shared_ptr<FILE> sp5(fopen("test.txt", "w"), [](FILE* p) {if (p) {cout << "Lambda: closing file" << endl;fclose(p);}});if (sp5) {fprintf(sp5.get(), "Hello, shared_ptr with deleter!\n");cout << "File written" << endl;}// 离开作用域时调用lambda删除器关闭文件return 0;
}

对于所有的指针不一定是 new 出来的对象,因此利用仿函数设置了删除器,这样就可以调用对应的删除


希望读者们多多三连支持

小编会继续更新

你们的鼓励就是我前进的动力!

请添加图片描述

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

相关文章:

  • 贵州城乡住房建设部网站网站关键词排名分析
  • 中文做网站关键词优化 搜索引擎
  • 做网站需要审批不企业网站建设需要多少钱
  • 台州市住房和城乡建设规划局网站宁波seo服务快速推广
  • 营销型网站建设要点seo顾问服务深圳
  • 生小孩去什么网站做登记html模板网站
  • 开平小学学生做平网站网站免费搭建
  • php网站制作 青岛百度联盟怎么加入
  • 大型网站开发成本广州发布紧急通知
  • 宁海企业网站建设网站推广与优化平台
  • 温江做网站的公司营销活动
  • 中山网站排名行业门户网站推广
  • 网络视频网站建设商业推广
  • 做公司网站的尺寸一般是多大如何在互联网推广自己的产品
  • 做网站如何让用户注册站长工具seo综合查询
  • 工业设计 做自己的网站 知乎网站快速排名推荐
  • 项城市建设方案公示在哪个网站seo专员很难吗
  • 北京模板网站建设费用培训课程网站
  • wordpress 设置站点地址seo品牌推广方法
  • 济宁百姓网免费发布信息网黑帽seo寄生虫
  • wordpress评论不准设置网站网站友情链接是什么
  • 做网站和网页有什么区别网络推广有哪些方法
  • 传奇广告查询网站磁力搜索器
  • 外链都没有的网站如何做排名的sem竞价托管费用
  • 一个域名可以做几个网站app优化排名
  • 河北新出现的传染病win优化大师有用吗
  • wordpress网页中添加3个音乐播放厦门seo搜索排名
  • 网站建设提示DNA错误网络seo软件
  • 建设部领导干部官方网站长春最新发布信息
  • 网站被降权会发生什么哪有恶意点击软件买的