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

C++ const&的一个特性,布布扣,bubuko.com

时间: 2024-10-07 02:35:24

C++ const&的一个特性的相关文章

MVC4项目中验证用户登录一个特性就搞定

在开发过程中,需要用户登陆才能访问指定的页面这种功能,微软已经提供了这个特性. // 摘要: // 表示一个特性,该特性用于限制调用方对操作方法的访问. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class AuthorizeAttribute : FilterAttribute, IAuthorizationF

python 之用装饰器@property,把方法变成一个特性

# -*- coding: utf-8 -*- """ Created on Sun Nov 13 23:19:03 2016 @author: toby """ #知识点:用装饰器@property,把方法变成一个特性 class Province:     memo = 'One of China\'s 23 provinces' #静态字段          def __init__(self,name,capital,leadership

[转]MVC4项目中验证用户登录一个特性就搞定

本文转自:http://www.mrhuo.com/Article/Details/470/A-Attribute-For-MVC4-Project-Used-To-Validate-User-Login 在开发过程中,需要用户登陆才能访问指定的页面这种功能,微软已经提供了这个特性. // 摘要: // 表示一个特性,该特性用于限制调用方对操作方法的访问. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inhe

转:C4项目中验证用户登录一个特性就搞定

转:C4项目中验证用户登录一个特性就搞定 在开发过程中,需要用户登陆才能访问指定的页面这种功能,微软已经提供了这个特性.     // 摘要:    //     表示一个特性,该特性用于限制调用方对操作方法的访问.    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]    public class AuthorizeAttrib

OC中的一个特性:延展

OC中的一个特性:延展其实说白了,延展就是弥补C语言中的前向申明,我们知道,在C语言中,如果你想调用一个函数的话,那么在此之前必须要声明一个这个函数,就是有前置性.OC中为了弥补C语言中的这个问题,就有了延展的概念,下面来看一下代码:Person.h[objc]  view plaincopy 1. //   2. //  Person.h   3. //  10_CategoryExtend   4. //   5. //  Created by jiangwei on 14-10-11.  

泥鳅般的const(一个小Demo彻底搞清楚)

#include<stdio.h> int main(){ int a = 3; int b = 5; /* C标准库函数中最常见格式, 目的是保护参数, 可读而不可修改参数内容 */ const int *p1 = &a; //含义: 从右到左"p1是一个指针变量, 可指向一个整型常量" //注意1: *p1是只读常量, 不可作为左值再次赋值; //注意2: p1是变量, 可以重新指向新的变量; //注意3: p1指向的变量a的值仍然可以修改; //*p1 = 7

从Windows/Linux文件系统设计的一个特性论软件架构的灵活性欠缺

当在Windows下打开一个文件时,此文件所在的路径全部被锁定. 路径锁定的意思是,文件本身.所在目录.上一层目录等,全部无法被重命名和重新移动. 实际上,这个锁定完全可以被移除. 方法是: 任何一个打开的文件将创建对原始文件数据IO的一个流连接,同时产生一个对文件元属性的临时快照的拓扑镜像. 这里的基本想法是:文件移动.重命名的操作并不影响文件的内容数据,可以看作是对文件属性的操作.(目录的概念应该是平面化的虚拟Tag标记,不应该是实体化的硬目录,这么一个早期Unix系统设计的特性早应该去掉了

[C++] 关于const的一个理所当然的想法造成的误解

const int p表示p是常量不可改变(当然也有办法改变,此处不究) 所以理所当然的想着const int *p就是p作为指针不可改变?(也就是说p不能改变指向?) 然而并非如此 const int *p表示的是*p(也就是p所指向的内容不可改变),那么怎样才能使指针不可改变呢? 如下图: 此图截自:http://blog.csdn.net/Eric_Jo/article/details/4138548(侵删) 更多关于const的详细内容也在上面所示网页.

django makemigrations的一个特性

Migrations will run the same way on the same dataset and produce consistent results, meaning that what you see in development and staging is, under the same circumstances, exactly what will happen in production. Django will make migrations for any ch