zoukankan      html  css  js  c++  java
  • C++ const&的一个特性

    最近在搜索类似scope exit的实现时,除了发现已经有人向标准委员会提出意见,还得到一些意外的C++特性,这个特性一直都存在,而且很有趣

    http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/

    总的来说就是:

    1.局部作用域内,使用const&接收函数值返回时,函数的返回值(即右值、临时对象)会被const&直接引用,直到const&退出作用域时才析构,这是一个特殊的优化,避免多一次复制构造。这个const&可以理解为在一个const的右值引用。而一般情况下,函数返回值(即右值、临时对象)是在函数调用表达式之后就被析构。上述优化延迟了函数返回值(即右值、临时对象)的析构时间。

    2.由于1的存在,所以下面的代码与直觉有差别

    class base;  // 注意,base没有虚析构函数

    class derive : public base;  // 注意,derive的析构函数不会被base的虚表派发

    derive foo();  // 返回一个derive的函数

    // 下面是某函数

    void bar()

    {

    const base& b = foo();

    // 作用域结束,derive的析构函数是会被调用的,而调用路径是derive::~derive,而不是base::~base virtual dispatch ~derive

    }

    出现这种行为的原因是,仅仅是因为const&接收了foo的返回值(即右值、临时对象),foo的返回值(即右值、临时对象)被延时析构。

    而直觉上,我们觉得上述代码的行为,应该是这样:

    derive d = foo();// 出现了一次复制构造,由foo的返回值(即右值、临时对象)构造左值d,之后foo的返回值(即右值、临时对象)析构

    const base& b = d;// const&引用左值d,当退出作用域时,d::~derive

    事实上:

    1.编译器不是产生d,~derive只作用于foo的返回值(即右值、临时对象)

    2.不要被base误导,因为这里的确有一个derive的值对象生成,作用域是函数bar,所以当bar返回后,这个derive对象就析构,自然就会调用~derive

  • 相关阅读:
    安装win7 ubuntu双系统
    idea maven打jar包
    mongodb入门
    mongodb备份与恢复
    使用cmd时cd命令失效
    vue 项目中使用阿里巴巴矢量图标库iconfont
    vue img标签用法
    vue 点击当前元素改变样式
    vue 路由跳转传参
    iview table绑定双击事件
  • 原文地址:https://www.cnblogs.com/rickerliang/p/3719071.html
Copyright © 2011-2022 走看看