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

区块链技术网站开发网站设计有哪些专业术语

区块链技术网站开发,网站设计有哪些专业术语,广东seo推广软件,我的世界怎么做赞助网站C 11 中的右值引用 右值引用的功能 首先#xff0c;我并不介绍什么是右值引用#xff0c;而是以一个例子里来介绍一下右值引用的功能#xff1a; #include iostream #include vector using namespace std; class obj { public : … C 11 中的右值引用 右值引用的功能 首先我并不介绍什么是右值引用而是以一个例子里来介绍一下右值引用的功能     #include iostream     #include vector     using namespace std;     class obj     {     public :         obj() { cout   create obj   endl; }         obj(const obj other) { cout   copy create obj   endl; }     };     vectorobj foo()     {         vectorobj c;         c.push_back(obj());         cout  ---- exit foo ----  endl;         return c;     }     int main()     {         vectorobj k;         k foo();     } 首先我们编译一下这个函数运行结果如下     tianfang g main.cpp     tianfang a.out      create obj       copy create obj      ---- exit foo ----      copy create obj      tianfang 可以看到对obj对象执行了两次构造。vector是一个常用的容器了我们可以很容易的分析这这两次拷贝构造的时机 foo函数第二行调用push_back的时候会在vector里建立一个obj的副本 main函数第二行执行复制函数的时候会把foo()返回的对象全部复制过来再次执行一次拷贝构造 由于对象的拷贝构造的开销是非常大的因此我们想就可能避免他们。其中第一次拷贝构造是vector的特性所决定的不可避免。但第二次拷贝构造在C 11中就是可以避免的了。     tianfang g -stdc11 main.cpp     tianfang a.out      create obj       copy create obj      ---- exit foo ----     tianfang 可以看到我们除了加上了一个-stdc11选项外什么都没干但现在就把第二次的拷贝构造给去掉了。它是如何实现这一过程的呢 在老版本中当我们执行第二行的赋值操作的时候执行过程如下 foo()函数返回一个临时对象这里用~tmp来标识它 执行vector的 函数将对象k中的现有成员删除将~tmp的成员复制到k中来 删除临时对象~tmp 在C11的版本中执行过程如下 foo()函数返回一个临时对象这里用~tmp来标识它 执行vector的 函数将对象k中的成员~tmp的成员互换此时k中的成员就被替换成了~tmp中的成员。 删除临时对象~tmp此时就删除了以前的k中的成员 关键的过程就是第2步它不是复制而是交换从而避免的成员的拷贝但效果却是一样的。不用修改代码性能却得到了提升对于程序员来说就是一份免费的午餐。 但是这份免费的午餐也不是无条件就可以获取的带上-stdc11编译时如果使用STL代码可以享用这份午餐但如果使用我们以前的老代码发现还是和以前的功能是一样的那么如何让我们以前的代码也能得到这个效率的提升呢     通过交换减少数据的拷贝 为了演示如何在我们的代码中也获取这个性能提升首先我先写了一个山寨的vector     #include iostream     #include vector     using namespace std;     class obj     {     public :         obj() { cout   create obj   endl; }         obj(const obj other) { cout   copy create obj   endl; }     };     template class T     class container     {     public:         T* value;     public:         container() : value(NULL) {};         ~container() { delete value; }          container(const container other)         {             value  new T(*other.value);         }         const container operator  (const container other)         {             delete value;             value  new T(*other.value);             return *this;         }         void push_back(const T item)         {             delete value;             value  new T(item);         }     };     containerobj foo()     {         containerobj c;         c.push_back(obj());         cout  ---- exit foo ----  endl;         return c;     }     int main()     {         containerobj k ;         k foo();         } 这个vector只能容纳一个元素但并不妨碍我们的演示其功能和前面的例子是一样的运行这段代码结果如下     tianfang make     g -stdc11 main.cpp     tianfang a.out      create obj       copy create obj      ---- exit foo ----      copy create obj      tianfang 如前所述仍然有两次拷贝构造。其实前面已经说过交换实现减少拷贝构造的原理那么我们可以通过修改 函数来手动实现这一过程。     const container operator (container other)     {         T* tmp value;         value  other.value;         other.value tmp;         return *this;     } 在VC中运行这段代码发现运行结果和预期一致      create obj       copy create obj      ---- exit foo ---- 但是gcc中却无法通过编译原因很简单gcc期望的赋值函数的参数是const型的而这里为了交换成员而不能使用const型。 那么虽然gcc中不能生效是否可以说在vc中就可以以这种形式获取性能提升呢答案是否定的。虽然在这段代码中这么写没有问题但赋值函数本身是期望复制功能的而不是交换。例如修改后下面的运行结果就不对了。     int main()     {         containerobj k, k2;         k foo();             //预期结果是复制但执行了交换         k2 k;     } gcc的告警是有道理的如果 函数实现的是复制功能虽然效率低点但保证了功能正确但如果实现的是交换的功能则不能保证功能一定正确。只有当 函数右边的对象为一个临时变量的时候由于临时变量会马上被删除掉此时的交换和复制的效果是一样的。其实VC也应该把这个告警加上才合适。 PS对临时变量定义和来源不清楚的朋友可以参考一下这篇文章。 现在的问题是我们无法在赋值函数里区分传入的是一个临时对象还是非临时对象因此只能执行复制操作。为了解决这一问题c中引入了一个新的赋值函数的重载形式     container operator (container other) 这个赋值函数通常称为移动赋值函数和老版本的相比它有两点区别 入参不是const型因此它是可以更改入参的值的从而实现交换操作 入参前面有两个号这个是C11引入的新语法称为右值引用它的使用方式和普通引用是一样的唯一的区别是可以指向临时变量。 现在我们就有两个版本的赋值函数了C11在语法级别也做了适应 如果入参是临时变量则执行移动赋值函数如果没有定义移动赋值函数则执行复制赋值函数以保证老版本代码能编译通过 如果入参不是临时变量则执行普通的复制赋值函数 现在我们实现一下山寨版的移动赋值函数     container operator (container other)     {         delete value;         value  other.value;         other.value  NULL;         return *this;     } 运行后结果就和我们期望的那样避免了成员的第二次的拷贝构造。 和移动赋值函数相应的也有一个一个移动构造函数也最好实现以下     container (container other)     {         value  other.value;         other.value  NULL;     } 我们也可以实现自己的右值引用版的重载函数这里就不多介绍了。 注意本文所示的代码只是为了演示和实现右值引用力求简洁并没有写得很完善一个典型的缺失就是在赋值函数中没有判断入参是否是本身请不要将其应用于项目中。 完善的版本请看MSDN文章如何编写一个移动构造函数其相应的对右值引用的介绍文章Rvalue引用声明:也非常值得一读。   通过std::move函数显式使用交换 首先看一下这段代码     class bigobj     {     public :         bigobj() { cout   create obj   endl; }         bigobj(const bigobj other) { cout   copy create obj   endl; }         bigobj(bigobj other) { cout   move create obj   endl; }     };     int main()     {         listbigobj list;         for(int i 0; i 3; i)         {             bigobj obj;             list.push_back(obj);         }     } 运行的时候就会发现虽然我们定义了移动构造函数但是它仍然会执行拷贝构造函数。这是因为编译器并不认为obj是临时变量。关于什么变量才是临时变量前文已经给了个链接来说明它简单的说我们能够看到的命名变量都不是临时变量。 虽然obj对象不是语言级别的临时变量但是从功能上来看它就是一个临时变量是可以使用移动构造函数来消除拷贝带来的性能损失的。为了解决这一问题C提供了一个move函数来把obj变量强制转换为右值引用这样就可以使用移动构造函数了。     for(int i 0; i 3; i)     {         bigobj obj;         list.push_back(std::move(obj));     } 不过需要注意的是和系统识别的临时变量而自动使用右值引用不同这种强制转换是有一定的风险的由于在push_back后执行了交换操作如果再次使用它会出现非预期的结果只有能确定该变量不会再次被使用才能执行这种转换。
http://www.zqtcl.cn/news/286609/

相关文章:

  • 网站横幅图片网页设计怎么创建站点
  • 网站建设页面设计图片开个送快餐网站怎么做
  • 北京免费网站建设模板下载南江县建设局网站
  • 温岭手机网站建设义乌市网站建设
  • 西安网站制作费用哪家装修公司比较好的
  • 硅谷网站开发薪酬wordpress热门吗
  • 红酒营销型网站建设天一建设网站
  • 做网站建设公司哪家好安徽省住房建设部官方网站
  • 网站被黑咋样的柳州正规网站制作公司哪家好
  • 莱芜网站开发代理四川网络推广服务
  • 应该知道的网站网站全网建设莱芜
  • 北京网站页设计制作广州专业网站改版
  • 重庆网站建设建站收费免费外链网盘
  • 做加盟代理的网站比较好的网页网站设计
  • 兴义网站开发企业标准备案平台官网
  • 蓝彩网络科技_齐齐哈尔微信营销_齐齐哈尔网站建设会员卡管理系统哪里买
  • 织梦门户网站做大后建个人免费网站用哪个
  • 深圳市建设管理中心西安官网seo
  • 网站开发工作方案自己做的网站怎么维护
  • 潍坊建设部门管理网站做网站如何接单
  • 定制高端网站建设设计建立的近义词
  • 企业网站建设进度邢台163官网
  • 17做网店网站池尾替代wordpress 搜索
  • 网站建设资料 优帮云商品分类标准
  • 鄂尔多斯 网站建设俐侎族网站建设背景
  • 佛山专业网站建设公司上海公司官网
  • 那里做网站好网站模板 登陆
  • 网站的服务器打不开wordpress 修改默认路径
  • 外贸网站做几种产品合肥网络公司哪个最好
  • 长乐区建设局网站一般通过什么渠道了解防灾减灾知识