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

国内做网站的顶尖公司网站公司市场营销方案

国内做网站的顶尖公司,网站公司市场营销方案,怎么给购物网站做推广,电子商务网站开发流程点击蓝字关注我们因公众号更改推送规则#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络#xff0c;侵删个人觉得最核心的变化是右值引用的引入#xff0c;右值引用是 C 走向现代化的最重要一步。建议每一位 C 开发者都应该深入去了解并充分使用它。…点击蓝字关注我们因公众号更改推送规则请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络侵删个人觉得最核心的变化是右值引用的引入右值引用是  C 走向现代化的最重要一步。建议每一位 C 开发者都应该深入去了解并充分使用它。右值引用是 C11 中最重要的新特性之一它解决了 C 中大量的历史遗留问题使 C 标准库的实现在多种场景下消除了不必要的额外开销如 std::vector, std::string)也使得另外一些标准库如 std::unique_ptr, std::function成为可能。即使你并不直接使用右值引用也可以通过标准库间接从这一新特性中受益。为了更好地理解标准库结合右值引用带来的优化我们有必要了解一下右值引用的重大意义。右值引用的意义通常解释为两大作用移动语义和完美转发。本文主要讨论移动语义。一、移动语义移动语义简单来说解决的是各种情形下对象的资源所有权转移的问题。而在 C11 之前移动语义的缺失是 C 饱受诟病的问题之一。举个例子。问题一如何将大象放入冰箱答案是众所周知的。首先你需要有一台特殊的冰箱这台冰箱是为了装下大象而制造的。你打开冰箱门将大象放入冰箱然后关上冰箱门。问题二如何将大象从一台冰箱转移到另一台冰箱普通解答打开冰箱门取出大象关上冰箱门打开另一台冰箱门放进大象关上冰箱门。2B 解答在第二个冰箱中启动量子复制系统克隆一只完全相同的大象然后启动高能激光将第一个冰箱内的大象气化消失。等等这个 2B 解答听起来很耳熟这不就是 C 中要移动一个对象时所做的事情吗“移动”这是一个三岁小孩都明白的概念。将大象资源从一台冰箱对象移动到另一台冰箱这个行为是如此自然没有任何人会采用先复制大象再销毁大象这样匪夷所思的方法。C 通过拷贝构造函数和拷贝赋值操作符为类设计了拷贝/复制的概念但为了实现对资源的移动操作调用者必须使用先复制、再析构的方式。否则就需要自己实现移动资源的接口。为了实现移动语义首先需要解决的问题是如何标识对象的资源是可以被移动的呢这种机制必须以一种最低开销的方式实现并且对所有的类都有效。C 的设计者们注意到大多数情况下右值所包含的对象都是可以安全的被移动的。右值相对应的还有左值是从 C 语言设计时就有的概念但因为其如此基础也是一个最常被忽略的概念。不严格的来说左值对应变量的存储位置而右值对应变量的值本身。C 中右值可以被赋值给左值或者绑定到引用。类的右值是一个临时对象如果没有被绑定到引用在表达式结束时就会被废弃。于是我们可以在右值被废弃之前移走它的资源进行废物利用从而避免无意义的复制。被移走资源的右值在废弃时已经成为空壳析构的开销也会降低。右值中的数据可以被安全移走这一特性使得右值被用来表达移动语义。以同类型的右值构造对象时需要以引用形式传入参数。右值引用顾名思义专门用来引用右值左值引用和右值引用可以被分别重载这样确保左值和右值分别调用到拷贝和移动的两种语义实现。对于左值如果我们明确放弃对其资源的所有权则可以通过std::move()来将其转为右值引用。std::move()实际上是 static_castT() 的简单封装。右值引用至少可以解决以下场景中的移动语义缺失问题1.按值传入参数按值传参是最符合人类思维的方式。基本的思路是如果传入参数是为了将资源交给函数接受者就应该按值传参。同时按值传参可以兼容任何的 cv-qualified 左值、右值是兼容性最好的方式。class People { public:// 按值传入字符串可接收左值、右值。// 接收左值时为复制接收右值时为移动People(string name) : name_(move(name)) // 显式移动构造将传入的字符串移入成员变量{}string name_; };People a(Alice); // 移动构造namestring bn  Bob; People b(bn); // 拷贝构造name构造a时调用了一次字符串的构造函数和一次字符串的移动构造函数。如果使用 const string name 接收参数那么会有一次构造函数和一次拷贝构造以及一次 non-trivial 的析构。尽管看起来很蛋疼尽管编译器还有优化但从语义来说按值传入参数是最优的方式。如果你要在构造函数中接收 std::shared_ptrX 并且存入类的成员这是非常常见的那么按值传入更是不二选择。拷贝 std::shared_ptrX 需要线程同步相比之下移动 std::shared_ptr 是非常轻松愉快的。2.按值返回和接收输入参数一样返回值按值返回也是最符合人类思维的方式。曾经有无数函数为了返回容器而不得不写成这样:// 一个按值语义定义的字符串拆分函数 void str_split(const string s, vectorstring* vec);这里不考虑分隔符假定分隔符是固定的。这样要求 vec在外部被事先构造此时尚无从得知vec的大小。即使函数内部有办法预测vec的大小因为函数并不负责构造vec很可能仍需要 resize。对这样的函数嵌套调用更是痛苦的事情谁用谁知道啊。有了移动语义就可以写成这样:vectorstring str_split(const string s) {vectorstring v;// ...return v; // v是左值但优先移动不支持移动时仍可复制。 }如果函数按值返回return 语句又直接返回了一个栈上的左值对象输入参数除外时标准要求优先调用移动构造函数如果不符再调用拷贝构造函数。尽管 v是左值仍然会优先采用移动语义返回 vector 从此变得云淡风轻。此外无论移动或是拷贝可能的情况下仍然适用编译器优化但语义不受影响。对于 std::unique_ptr 来说这简直就是福音。unique_ptrSomeObj create_obj(/*...*/) {unique_ptrSomeObj ptr(new SomeObj(/*...*/));ptr-foo(); // 一些可能的初始化return ptr; }当然还有更简单的形式:unique_ptrSomeObj create_obj(/*...*/) {return unique_ptrSomeObj(new SomeObj(/*...*/)); }在工厂类中这样的语义是非常常见的。返回 unique_ptr 能够明确对所构造对象的所有权转移特别的这样的工厂类返回值可以被忽略而不会造成内存泄露。上面两种形式分别返回栈上的左值和右值但都适用移动语义unique_ptr 不支持拷贝。3.接收右值表达式没有移动语义时以表达式的值例为函数调用初始化对象或者给对象赋值是这样的vectorstring str_split(const string s); // 返回的vector用以拷贝构造对象v。为v申请堆内存复制数据然后析构临时对象释放堆内存。 vectorstring v  str_split(1,2,3);  vectorstring v2; // 返回的vector被复制给对象v拷贝赋值操作符。需要先清理v2中原有数据将临时对象中的数据复制给v2然后析构临时对象。 v2  str_split(1,2,3);注v 的拷贝构造调用有可能被优化掉尽管如此在语义上仍然是有一次拷贝操作。同样的代码在支持移动语义的世界里就变得更美好了。vectorstring str_split(const string s); // 返回的vector用以移动构造对象v。v直接取走临时对象的堆上内存无需新申请。之后临时对象成为空壳不再拥有任何资源析构时也无需释放堆内存。 vectorstring v  str_split(1,2,3);  vectorstring v2; // 返回的vector被移动给对象v移动赋值操作符。先释放v2原有数据然后直接从返回值中取走数据然后返回值被析构。 v2  str_split(1,2,3);注v 的移动构造调用有可能被优化掉尽管如此在语义上仍然是有一次移动操作。不用多说也知道上面的形式是多么常用和自然。而且这里完全没有任何对右值引用的显式使用性能提升却默默的实现了。4.对象存入容器这个问题和前面的构造函数传参是类似的。不同的是这里是按两种引用分别传参。参见 std::vector 的 push_back 函数。void push_back( const T value ); // (1) void push_back( T value ); // (2)不用多说自然是左值调用 1 右值调用 2。如果你要往容器内放入超大对象那么版本 2 自然是不 2 选择。vectorvectorstring vv;vectorstring v  {123, 456}; v.push_back(789); // 临时构造的string类型右值被移动进容器v vv.push_back(move(v)); // 显式将v移动进vv困扰多年的难言之隐是不是一洗了之了5.std::vector 的增长又一个隐蔽的优化。当 vector 的存储容量需要增长时通常会重新申请一块内存并把原来的内容一个个复制过去并删除。对复制并删除改用移动就够了。对于像 vectorstring 这样的容器如果频繁插入造成存储容量不可避免的增长时移动语义可以带来悄无声息而且美好的优化。6.std::unique_ptr放入容器曾经由于 vector 增长时会复制对象像 std::unique_ptr 这样不可复制的对象是无法放入容器的。但实际上 vector 并不复制对象而只是“移动”对象。所以随着移动语义的引入std::unique_ptr 放入 std::vector 成为理所当然的事情。容器中存储 std::unique_ptr 有太多好处。想必每个人都写过这样的代码MyObj::MyObj() {for (...) {vec.push_back(new T());}// ... }MyObj::~MyObj() {for (vectorT*::iterator iter  vec.begin(); iter ! vec.end(); iter) {if (*iter) delete *iter;}// ... }繁琐暂且不说异常安全也是大问题。使用 vectorunique_ptrT完全无需显式析构unqiue_ptr 自会打理一切。完全不用写析构函数的感觉你造吗unique_ptr 是非常轻量的封装存储空间等价于裸指针但安全性强了一个世纪。实际中需要共享所有权的对象指针是比较少的但需要转移所有权是非常常见的情况。auto_ptr 的失败就在于其转移所有权的繁琐操作。unique_ptr 配合移动语义即可轻松解决所有权传递的问题。注如果真的需要共享所有权那么基于引用计数的 shared_ptr 是一个好的选择。shared_ptr 同样可以移动。由于不需要线程同步移动 shared_ptr 比复制更轻量。7.std::thread 的传递thread 也是一种典型的不可复制的资源但可以通过移动来传递所有权。同样 std::future std::promise std::packaged_task 等等这一票多线程类都是不可复制的也都可以用移动的方式传递。二、完美转发除了移动语义右值引用还解决了 C03 中引用语法无法转发右值的问题实现了完美转发才使得 std::function 能有一个优雅的实现。这部分不再展开了。三、总结移动语义绝不是语法糖而是带来了 C 的深刻革新。移动语义不仅仅是针对库作者的任何一个程序员都有必要去了解它。尽管你可能不会去主动为自己的类实现移动语义但却时时刻刻都在享受移动语义带来的受益。因此这绝不意味着这是一个可有可无的东西。所以如果你要写出优雅的 Modern C 代码应该多使用右值引用喜欢它拥抱它。如果你年满18周岁以上又觉得学【C语言】太难想尝试其他编程语言那么我推荐你学Python现有价值499元Python零基础课程限时免费领取限10个名额▲扫描二维码-免费领取推荐阅读OPPO 推出“安第斯智能云”三大技术护城河已形成“告别 8 万行 C 代码我用 4 千行 C 代码就搞定了”这才是B站的正确打开方式Intellij IDEA 神级插件效率提升 10 倍点击 阅读原文 了解更多
http://www.huolong8.cn/news/87061/

相关文章:

  • asp网站空间申请百度排名优化咨询电话
  • 全县网站建设情况通报网站云空间大小
  • 网站建设搭建步骤陕西网站维护
  • 网站写动态新闻有什么好处网页制作方法视频教程
  • 中企动力做网站贵吗爱南宁app下载官网
  • 郑州做网站哪里便宜成为软件工程师的条件
  • 阿里云网站空间多合一可拖曳修改优化网站建设
  • 网站建设与维护 参考文献福州外包seo公司
  • 好的logo设计网站ui设计是什么意思啊
  • 健康私人定制网站怎么做麦壳云网站建设
  • 南京网站推广排名江门网站推广哪家好
  • 房地产网站建设存在问题企业搜索
  • 建立网站如何wordpress折叠代码
  • 长沙中小企业网站建设网站开发属于什么行业
  • 微信官方网站公众平台昆明网络推广招聘
  • 网站开发文档带er图公司查名网站
  • 更适合企业网站建设的cms系统中国新闻社是事业编制吗
  • 扬州网站建设sutengseo做网站
  • 建站公司用哪家服务器免费可以绑定域名网站空间
  • 2免费做网站今天的新闻直播
  • 烘焙食品网站建设需求分析全网网站快速排名推广软件
  • 如何申请com网站wordpress表单提交的邮箱
  • 镇江做网站东莞寮步做网站的有吗
  • 蓝田网站建设百度查看订单
  • 企业网站建设的意义和效果网站title设置
  • 西安做网站公司商业展厅手绘设计图
  • 北京大型网站建设上海seo推广平台
  • 手机免费制作自己的网站网站支付页面设计
  • 网站设计工具建设网站需要什么内容
  • 怎么建设课程的网站站长推荐网站