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

一个云主机 多个网站冠县网站建设gxsh

一个云主机 多个网站,冠县网站建设gxsh,网易企业邮箱下载官网,一般做外单的有哪些网站http://blog.csdn.net/lanxuezaipiao/article/details/41603883 导读 最近在补看《C Primer Plus》第六版#xff0c;这的确是本好书#xff0c;其中关于智能指针的章节解析的非常清晰#xff0c;一解我以前的多处困惑。C面试过程中#xff0c;很多面试官都喜欢问智能指针相…http://blog.csdn.net/lanxuezaipiao/article/details/41603883 导读 最近在补看《C Primer Plus》第六版这的确是本好书其中关于智能指针的章节解析的非常清晰一解我以前的多处困惑。C面试过程中很多面试官都喜欢问智能指针相关的问题比如你知道哪些智能指针shared_ptr的设计原理是什么如果让你自己设计一个智能指针你如何完成等等……。而且在看开源的C项目时也能随处看到智能指针的影子。这说明智能指针不仅是面试官爱问的题材更是非常有实用价值。 下面是我在看智能指针时所做的笔记希望能够解决你对智能指针的一些困扰。 目录 智能指针背后的设计思想C智能指针简单介绍为什么摒弃auto_ptrunique_ptr为何优于auto_ptr如何选择智能指针 正文 1. 智能指针背后的设计思想 我们先来看一个简单的例子 void remodel(std::string str) {std::string * ps new std::string(str);...if (weird_thing())throw exception();str *ps; delete ps;return; }当出现异常时weird_thing()返回truedelete将不被执行因此将导致内存泄露。 如何避免这种问题有人会说这还不简单直接在throw exception();之前加上delete ps;不就行了。是的你本应如此问题是很多人都会忘记在适当的地方加上delete语句连上述代码中最后的那句delete语句也会有很多人忘记吧如果你要对一个庞大的工程进行review看是否有这种潜在的内存泄露问题那就是一场灾难 这时我们会想当remodel这样的函数终止不管是正常终止还是由于出现了异常而终止本地变量都将自动从栈内存中删除—因此指针ps占据的内存将被释放如果ps指向的内存也被自动释放那该有多好啊。 我们知道析构函数有这个功能。如果ps有一个析构函数该析构函数将在ps过期时自动释放它指向的内存。但ps的问题在于它只是一个常规指针不是有析构凼数的类对象指针。如果它指向的是对象则可以在对象过期时让它的析构函数删除指向的内存。 这正是 auto_ptr、unique_ptr和shared_ptr这几个智能指针背后的设计思想。我简单的总结下就是将基本类型指针封装为类对象指针这个类肯定是个模板以适应不同基本类型的需求并在析构函数里编写delete语句删除指针指向的内存空间。 因此要转换remodel()函数应按下面3个步骤进行 包含头义件memory智能指针所在的头文件将指向string的指针替换为指向string的智能指针对象删除delete语句。 下面是使用auto_ptr修改该函数的结果 # include memory void remodel (std::string str) {std::auto_ptrstd::string ps (new std::string(str))...if (weird_thing ())throw exception() str *ps // delete ps NO LONGER NEEDEDreturn; }2. C智能指针简单介绍 STL一共给我们提供了四种智能指针auto_ptr、unique_ptr、shared_ptr和weak_ptr本文章暂不讨论。 模板auto_ptr是C98提供的解决方案C11已将将其摒弃并提供了另外两种解决方案。然而虽然auto_ptr被摒弃但它已使用了好多年同时如果您的编译器不支持其他两种解决力案auto_ptr将是唯一的选择。 使用注意点 所有的智能指针类都有一个explicit构造函数以指针作为参数。比如auto_ptr的类模板原型为 templetclass T class auto_ptr {explicit auto_ptr(X* p 0) ; ... }; 因此不能自动将指针转换为智能指针对象必须显式调用 shared_ptrdouble pd; double *p_reg new double; pd p_reg; // not allowed (implicit conversion) pd shared_ptrdouble(p_reg); // allowed (explicit conversion) shared_ptrdouble pshared p_reg; // not allowed (implicit conversion) shared_ptrdouble pshared(p_reg); // allowed (explicit conversion) 对全部三种智能指针都应避免的一点 string vacation(I wandered lonely as a cloud.); shared_ptrstring pvac(vacation); // No pvac过期时程序将把delete运算符用于非堆内存这是错误的。 使用举例 #include iostream #include string #include memoryclass report { private:std::string str; public:report(const std::string s) : str(s) {std::cout Object created.\n;}~report() {std::cout Object deleted.\n;}void comment() const {std::cout str \n;} };int main() {{std::auto_ptrreport ps(new report(using auto ptr));ps-comment();}{std::shared_ptrreport ps(new report(using shared ptr));ps-comment();}{std::unique_ptrreport ps(new report(using unique ptr));ps-comment();}return 0; }3. 为什么摒弃auto_ptr 先来看下面的赋值语句: auto_ptr string ps (new string (I reigned lonely as a cloud.”; auto_ptrstring vocation; vocaticn ps;上述赋值语句将完成什么工作呢如果ps和vocation是常规指针则两个指针将指向同一个string对象。这是不能接受的因为程序将试图删除同一个对象两次——一次是ps过期时另一次是vocation过期时。要避免这种问题方法有多种 定义陚值运算符使之执行深复制。这样两个指针将指向不同的对象其中的一个对象是另一个对象的副本缺点是浪费空间所以智能指针都未采用此方案。建立所有权ownership概念。对于特定的对象只能有一个智能指针可拥有这样只有拥有对象的智能指针的构造函数会删除该对象。然后让赋值操作转让所有权。这就是用于auto_ptr和uniqiie_ptr 的策略但unique_ptr的策略更严格。创建智能更高的指针跟踪引用特定对象的智能指针数。这称为引用计数。例如赋值时计数将加1而指针过期时计数将减1,。当减为0时才调用delete。这是shared_ptr采用的策略。 当然同样的策略也适用于复制构造函数。 每种方法都有其用途但为何说要摒弃auto_ptr呢 下面举个例子来说明。 #include iostream #include string #include memory using namespace std;int main() {auto_ptrstring films[5] {auto_ptrstring (new string(Fowl Balls)),auto_ptrstring (new string(Duck Walks)),auto_ptrstring (new string(Chicken Runs)),auto_ptrstring (new string(Turkey Errors)),auto_ptrstring (new string(Goose Eggs))};auto_ptrstring pwin;pwin films[2]; // films[2] loses ownership. 将所有权从films[2]转让给pwin此时films[2]不再引用该字符串从而变成空指针cout The nominees for best avian baseballl film are\n;for(int i 0; i 5; i)cout *films[i] endl;cout The winner is *pwin endl;cin.get();return 0; }运行下发现程序崩溃了原因在上面注释已经说的很清楚films[2]已经是空指针了下面输出访问空指针当然会崩溃了。但这里如果把auto_ptr换成shared_ptr或unique_ptr后程序就不会崩溃原因如下 使用shared_ptr时运行正常因为shared_ptr采用引用计数pwin和films[2]都指向同一块内存在释放空间时因为事先要判断引用计数值的大小因此不会出现多次删除一个对象的错误。使用unique_ptr时编译出错与auto_ptr一样unique_ptr也采用所有权模型但在使用unique_ptr时程序不会等到运行阶段崩溃而在编译器因下述代码行出现错误 unique_ptrstring pwin; pwin films[2]; // films[2] loses ownership. 指导你发现潜在的内存错误。 这就是为何要摒弃auto_ptr的原因一句话总结就是避免潜在的内存崩溃问题。 4. unique_ptr为何优于auto_ptr 可能大家认为前面的例子已经说明了unique_ptr为何优于auto_ptr也就是安全问题下面再叙述的清晰一点。 请看下面的语句: 请看下面的语句: auto_ptrstring p1(new string (auto) //#1 auto_ptrstring p2; //#2 p2 p1; 在语句#3中p2接管string对象的所有权后p1的所有权将被剥夺。前面说过这是好事可防止p1和p2的析构函数试图刪同—个对象 但如果程序随后试图使用p1这将是件坏事因为p1不再指向有效的数据。 下面来看使用unique_ptr的情况 unique_ptrstring p3 (new string (auto); //#4 unique_ptrstring p4 //#5 p4 p3; 编译器认为语句#6非法避免了p3不再指向有效数据的问题。因此unique_ptr比auto_ptr更安全。 但unique_ptr还有更聪明的地方。 有时候会将一个智能指针赋给另一个并不会留下危险的悬挂指针。假设有如下函数定义 unique_ptrstring demo(const char * s) {unique_ptrstring temp (new string (s)) return temp }并假设编写了如下代码 unique_ptrstring ps; ps demo(Uniquely special)demo()返回一个临时unique_ptr然后ps接管了原本归返回的unique_ptr所有的对象而返回时临时的 unique_ptr 被销毁也就是说没有机会使用 unique_ptr 来访问无效的数据换句话来说这种赋值是不会出现任何问题的即没有理由禁止这种赋值。实际上编译器确实允许这种赋值这正是unique_ptr更聪明的地方。 总之党程序试图将一个 unique_ptr 赋值给另一个时如果源 unique_ptr 是个临时右值编译器允许这么做如果源 unique_ptr 将存在一段时间编译器将禁止这么做比如 unique_ptrstring pu1(new string (hello world)); unique_ptrstring pu2; pu2 pu1; // #1 not allowed unique_ptrstring pu3; pu3 unique_ptrstring(new string (You)); // #2 allowed其中#1留下悬挂的unique_ptr(pu1)这可能导致危害。而#2不会留下悬挂的unique_ptr因为它调用 unique_ptr 的构造函数该构造函数创建的临时对象在其所有权让给 pu3 后就会被销毁。这种随情况而已的行为表明unique_ptr 优于允许两种赋值的auto_ptr 。 当然您可能确实想执行类似于#1的操作仅当以非智能的方式使用摒弃的智能指针时如解除引用时这种赋值才不安全。要安全的重用这种指针可给它赋新值。C有一个标准库函数std::move()让你能够将一个unique_ptr赋给另一个。下面是一个使用前述demo()函数的例子该函数返回一个unique_ptrstring对象 使用move后原来的指针仍转让所有权变成空指针可以对其重新赋值。 unique_ptrstring ps1, ps2; ps1 demo(hello); ps2 move(ps1); ps1 demo(alexia); cout *ps2 *ps1 endl;5. 如何选择智能指针 在掌握了这几种智能指针后应使用哪种智能指针呢 1如果程序要使用多个指向同一个对象的指针应选择shared_ptr。这样的情况包括 有一个指针数组并使用一些辅助指针来标示特定的元素如最大的元素和最小的元素 两个对象包含都指向第三个对象的指针 STL容器包含指针。 很多STL算法都支持复制和赋值操作这些操作可用于shared_ptr但不能用于unique_ptr编译器发出warning和auto_ptr行为不确定。如果你的编译器没有提供shared_ptr可使用Boost库提供的shared_ptr。 2如果程序不需要多个指向同一个对象的指针则可使用unique_ptr。如果函数使用new分配内存并返还指向该内存的指针将其返回类型声明为unique_ptr是不错的选择。这样所有权转让给接受返回值的unique_ptr而该智能指针将负责调用delete。可将unique_ptr存储到STL容器在那个只要不调用将一个unique_ptr复制或赋给另一个算法如sort()。例如可在程序中石油类似于下面的代码段。 unique_ptrint make_int(int n) {return unique_ptrint(new int(n)); } void show(unique_ptrint p1) {cout *a ; } int main() {...vectorunique_ptrint vp(size);for(int i 0; i vp.size(); i)vp[i] make_int(rand() % 1000); // copy temporary unique_ptrvp.push_back(make_int(rand() % 1000)); // ok because arg is temporaryfor_each(vp.begin(), vp.end(), show); // use for_each()... }其中push_back调用没有问题因为它返回一个临时unique_ptr该unique_ptr被赋给vp中的一个unique_ptr。另外如果按值而不是按引用给show()传递对象for_each()将非法因为这将导致使用一个来自vp的非临时unique_ptr初始化pi而这是不允许的。前面说过编译器将发现错误使用unique_ptr的企图。 在unique_ptr为右值时可将其赋给shared_ptr这与将一个unique_ptr赋给一个需要满足的条件相同。与前面一样在下面的代码中make_int()的返回类型为unique_ptrint unique_ptrint pup(make_int(rand() % 1000)); // ok shared_ptrint spp(pup); // not allowed, pup as lvalue shared_ptrint spr(make_int(rand() % 1000)); // ok模板shared_ptr包含一个显式构造函数可用于将右值unique_ptr转换为shared_ptr。shared_ptr将接管原来归unique_ptr所有的对象。在满足unique_ptr要求的条件时也可使用auto_ptr但unique_ptr是更好的选择。如果你的编译器没有unique_ptr可考虑使用Boost库提供的scoped_ptr它与unique_ptr类似。
http://wiki.neutronadmin.com/news/141889/

相关文章:

  • 移动网站开发试验报告免费发布信息网网站
  • 网站服务器提供什么服务wordpress 登录页美化
  • 优秀网站建设方案建设档案员证书查询网站
  • 公司网站建设宣传wordpress 经典博客主题
  • 思睿鸿途北京网站建设织梦如何做中英文网站
  • 北京外贸网站制作公司网站过期后
  • 思茅网站建设有没有专门做家乡图片的网站
  • 申请一个网站得多钱联想企业网站建设的思路
  • 买源码做网站简单嘛wordpress页面缓存
  • 营业执照年报官网入口萌新seo
  • 网站内容好网站开发猪八戒
  • 做网站如何选择颜色阿里巴巴网站备案
  • 千鸟云网站建设怎么做一淘宝客网站吗
  • 泗县住房和城乡建设局网站上海网站建设shwzzz
  • joomla 网站图标网站配色模板
  • 网站免备案如何设公司产品购物网站
  • 建大型网站公司简介企业网络管理系统
  • 个人网站是啥电子商务网站中最基本的系统是
  • 免费推广网站大全下载网站app 开发
  • 网站设置访问密码网站首页的动态效果图怎么做
  • 专业找工作网站下载网站选项卡
  • 手机网站左右滑动平台开发是做什么的
  • 做任务给佣金的网站小程序平台商城
  • 东莞市网站seo内容优化吉利汽车网站开发环境分析
  • 做电商运营还是网站运营哪个好wordpress配置数据库失败6
  • 凡科建站网址红色经典ppt模板免费下载
  • 廊坊seo网站管理网站备案是域名还是空间
  • 加强政务公开与网站建设百度上做推广怎么做
  • 门户网站建设对策及建议网站开发培训课程表
  • 做网站切图网页转向网站