Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >返回类型引用(ref-qualified)的C++成员函数暗示了什么?

返回类型引用(ref-qualified)的C++成员函数暗示了什么?

原创
作者头像
mariolu
发布于 2023-09-03 08:08:09
发布于 2023-09-03 08:08:09
29800
代码可运行
举报
运行总次数:0
代码可运行

一、引子:

返回引用类型的成员函数是 暗示了使用它的this指针是左值还是右值。反过来说,如果一个成员函数不返回引用类型,那么对this指针是左值还是右值都是调用同一个函数。

比如说:这段代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Obj o{2}; o.getVal();

跟这段代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Obj{2}.getVal()

使用了同一个getVal()函数。

那理解到这里是对的吗?


二、解释:

先说结论,来说一个c++的一个理解。

如果成员函数是有一致性(consistency)的,那么non-const, non-static的函数 总是要被&( &-qualified)。

举个例子

这个例子里你不能做

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
inc(A{}) 

但是可以做

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 A{}.inc().

不能做是因为内部语言有意这么设计,因为 A{} 传给 inc( A{} ) 函数,你期待这个函数对暂存值A{}进行修改,但是A{}传进去后就销毁了,caller并没有感知到。而另一种写法A{}.inc()是被允许的。这是consistency的做法。


三、扩展

当然书写设计自己的成员函数,不一定都有必要去做ref-qualified,但是这里我带你看一些使用ref-qualified的真实例子。

3.1、只对右值形参操作

一种场景是上面这个例子,防止用户错误地将一个暂存值传入给函数,然后期盼这个函数做出修改。(换句话说,只允许成员函数操作右值形参。这个情况这个函数应该被修饰为 &&-qualified)。比如说这个函数会从对象object取到资源resources,然后处于未指定的状态。

有时候一个成员函数需要有能力从类中取到资源,那么他就能被右值rvalue call到,否则,它就是const修饰的成员函数。看这个例子std::string::substr有用const&重载,也有用&&重载的两个函数。

3.2、将一个函数的return value传递作为给另一个函数的输入

这种场景需要&- overload和&&-overload (+ potentiallyconst/volatilevariations)。可以看std::optional::value这个例子。


四、未来C++23

在 C++23 有显式的对象, 因为用户可以forward上次的references. 也有可能简单地写一个non-static成员函数。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C++23新特性:显式对象形参与显式对象成员函数
C++23标准引入了一项重要的语言特性——显式对象形参与显式对象成员函数,又名“推导 this”(Deducing this,P0847R7)。这一特性改变了我们编写成员函数的方式,为模板元编程和设计模式的实现带来了新的可能性。
码事漫谈
2025/04/10
1410
C++23新特性:显式对象形参与显式对象成员函数
深入理解C++11右值引用与移动语义:高效编程的基石
在现代C++编程中,性能优化和资源管理一直是开发者追求的目标。C++11引入的右值引用(rvalue reference)和移动语义(move semantics)为解决这些问题提供了强有力的工具。通过右值引用,我们能够更高效地处理临时对象;而移动语义的引入,则进一步优化了对象的资源转移和管理。在这篇文章中,我们将深入探索右值引用和移动语义的核心概念、实现原理,以及它们在实际开发中的应用场景。
suye
2024/11/21
1760
深入理解C++11右值引用与移动语义:高效编程的基石
现代C++之万能引用、完美转发、引用折叠(万字长文)
0.导语1.问题引入2.引入万能引用3.万能引用出现场合4.理解左值与右值4.1 精简版4.2 完整版4.3 生命周期延长4.4 生命周期延长应用5.区分万能引用6.表达式的左右值性与类型无关7.引用折叠和完美转发7.1 引用折叠之本质细节7.2 示例与使用7.3 std::move()与std::forward()源码剖析8.不要返回本地变量的引用9.总结10.补充
公众号guangcity
2019/12/30
6.9K0
现代C++之万能引用、完美转发、引用折叠(万字长文)
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
c++11 标准的发布为 c++ 带来了革命性的变化,引入了许多强大的新特性,使代码更简洁、高效且现代化。这些特性不仅提升了开发效率,还优化了性能,是现代 c++ 编程的重要基石。本篇文章,我们将重点探讨 c++11 的几个核心改进:列表初始化、右值引用和移动语义、类的新默认成员函数以及lambda表达式。
ephemerals__
2025/04/10
1500
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
【译】理解C和C++中的左值和右值
https://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c/
用户6557940
2022/07/24
1.3K0
在 C++ 中,你甚至可以 b()()()(); ——介绍 ref qualifier
在传统 C++ 中,成员函数通过 this 指针访问。可以处理所有需要左值的情况。
春帆
2018/07/25
1.3K0
C++ 左值和右值
在C++11之前,一个变量分为左值和右值:左值是可以放在=运算符左边的值,有名字,可以用&运算符取地址(如 int n = 10;n即为左值);右值则是只能放在=运算符右边,没有名字,不能用&运算符取地址的值,一般是临时变量(非引用返回的函数返回值、表达式等,例如函数int func()的返回值,表达式a+b的返回值)、lambda表达式、不跟对象关联的字面量值,例如true,100等。
永远的Alan
2023/04/15
1.3K0
深入解析C++的auto自动类型推导
关键字auto在C++98中的语义是定义一个自动生命周期的变量,但因为定义的变量默认就是自动变量,因此这个关键字几乎没有人使用。于是C++标准委员会在C++11标准中改变了auto关键字的语义,使它变成一个类型占位符,允许在定义变量时不必明确写出确切的类型,让编译器在编译期间根据初始值自动推导出它的类型。这篇文章我们来解析auto自动类型推导的推导规则,以及使用auto有哪些优点,还有罗列出自C++11重新定义了auto的含义以后,在之后发布的C++14、C++17、C++20标准对auto的更新、增强的功能,以及auto有哪些使用限制。
爱分享
2024/04/11
4430
深入解析C++的auto自动类型推导
C++进阶之路:再谈构造函数、static成员、友元(类与对象_下篇)
虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,
Srlua
2024/10/23
1060
C++进阶之路:再谈构造函数、static成员、友元(类与对象_下篇)
C++ 中的左值和右值
一直以来,我都对C++中左值(lvalue)和右值(lvalue)的概念模糊不清。我认为是时候好好理解他们了,因为这些概念随着C++语言的进化变得越来越重要。
全栈程序员站长
2022/07/23
2.1K0
左右值引用和移动语义
什么是左值、右值呢?一种极不严谨的理解为:在赋值的时候,能够被放到等号左边的值为左值,放在右边的值为右值。例如:
艰默
2023/02/26
9520
左右值引用和移动语义
[Effective Modern C++(11&14)]Chapter 5: Rvalue References, Move Semantics, PF
1. 理解std::move和std::forward 从std::move和std::forward不能做的地方开始入手是有帮助的,std::move不会移动任何值,std::forward也不会转发任何东西,在运行时,他们不会产生可执行代码,一个字节也不会:)。他们实际上是执行转换的函数模板。std::move无条件的把它的参数转换成一个右值,而std::forward在特定条件下将参数转换成右值。 //c++11中std::move的简化版本 template<typename T> typename
昊楠Hacking
2018/05/26
5.2K0
【C++篇】C++类与对象深度解析(三):类的默认成员函数详解
运算符重载允许我们为类对象自定义运算符的行为,这样当我们对类对象使用这些运算符时,它们会按照我们定义的方式执行。如果没有定义对应的运算符重载,编译器将会报错,因为它不知道如何处理这些运算符。
半截诗
2024/10/09
1690
【C++篇】C++类与对象深度解析(三):类的默认成员函数讲解
4.1 运算符重载的基本概念 运算符重载允许我们为类对象自定义运算符的行为,这样当我们对类对象使用这些运算符时,它们会按照我们定义的方式执行。如果没有定义对应的运算符重载,编译器将会报错,因为它不知道如何处理这些运算符。
熬夜学编程的小王
2024/11/20
1090
【C++篇】C++类与对象深度解析(三):类的默认成员函数讲解
【Modern C++】深入理解左值、右值
作为C/C++开发人员,在平时的项目开发过程中,或多或少的听过左值和右值的概念,甚至在编译器报错的时候,遇到过lvalue和rvalue等字样;甚至使用过std::move(),但是不知道其含义。作为多年的C++开发人员,一直以来,对左值右值的理解没有一个系统的认识,总感觉似懂非懂。今天,借助本文,详细的介绍下这些知识点,并从代码实例的角度去分析什么是左值或者右值,同时,也算是给自己知识点做一个总结。
高性能架构探索
2022/08/25
1.1K0
【Modern C++】深入理解左值、右值
C++中的万能引用和完美转发
则会得到一个大大的编译错误。因为上面的模板函数只能接受左值或者左值引用(左值一般是有名字的变量,可以取到地址的),我们当然可以重载一个接受右值的模板函数,如下也可以达到效果。
卡尔曼和玻尔兹曼谁曼
2019/01/25
3.9K2
C++11-右值引用/新的类功能/可变参数列表
C++11-右值引用/新的类功能/可变参数列表 零、前言 一、右值引用 1、左值和右值 2、左值引用和右值引用 3、右值引用 4、移动语义 5、右值引用引用左值 6、完美转发 7、右值引用作用 二、新的类功能 1、默认成员函数 2、移动构造和移动赋值 三、可变参数列表 1、参数包的展开 2、STL中的emplace 零、前言 本章继续跟着上章讲解C++11的新语法特性,主要包括右值引用 一、右值引用 引入及概念: C++98中提出了引用的概念,引用即别名,引用变量与其引用实体公共同一块内存空间,而
用户9645905
2022/11/30
8920
C++11-右值引用/新的类功能/可变参数列表
C++:31---对象引用和赋值
一、对象移动概述 C++11标准引入了“对象移动”的概念 对象移动的特性是:可以移动而非拷贝对象 在C++旧标准中,没有直接的方法移动对象。因此会有很多不必要的资源拷贝 标准库容器、string、share_ptr类既支持移动也支持拷贝。IO类和unique_ptr类可以移动但不能拷贝 对象移动的特点 在很多情况下会发生对象拷贝的现象,对象拷贝之后就被销毁了,在这种情况下,对象移动而非对象拷贝会大幅度提升性能 使用移动而非拷贝的另一个原因是:类似于IO类或unique_ptr这样的类,这些类都不能被共享资
用户3479834
2021/02/03
1.8K0
【C++初阶】一文讲通默认成员函数~类和对象(中)
默认成员函数就是用户没有显式实现,编译器会自动生成的成员函数称为默认成员函数(注意并不意味着只有编译器生成的才是默认成员函数)。 一个类,我们不写任何默认成员函数的情况下编译器会生成以下6个默认成员函数,需要注意的是这6个中最重要的是前4个,最后两个取地址重载不重要,稍微了解一下即可。
fhvyxyci
2024/10/20
1600
【C++初阶】一文讲通默认成员函数~类和对象(中)
C++的复杂,C是原罪:从值类别说开去
我们知道 C++ 的值类别包括左值、右值、纯右值、广义左值、将亡值。可 C++ 到底是经历了什么才硬要把这件事情搞得如此复杂呢?我们不妨从 C 语言、汇编和 C++ 设计发展的角度来分析一下这个问题~
腾讯云开发者
2023/10/27
7660
C++的复杂,C是原罪:从值类别说开去
推荐阅读
相关推荐
C++23新特性:显式对象形参与显式对象成员函数
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验