c++ - 关于实现类对象的三个问题
问题描述
问题:
我使用 cppreference.com 上描述的模板来指导我实现一些功能,例如push()(在我的例子中是enqueue())。在 cppreference.com 上,提供了以下模板:
(a) push(const value_type & value); (b) push(value_type && value);
https://en.cppreference.com/w/cpp/container/queue/push
既然(a)需要一个引用,那么文字是如何添加到队列中的?
此外,如果我实现一个功能
enqueue(Queue const & other)
使用功能
enqueue(T const & value)
通过迭代“其他”并将每个值排入“其他”中,这不会添加“其他”中值的“深层”副本吗?因此,我不应该传递对其他的引用,而是传递一个副本?
此外,“&&”是什么意思?
这两个功能如何
(a) const T & front() const (b) T & front()
由编译器区分?此外,(a)在函数名称后有一个 const 意味着外部用户将无法修改前面的变量?您甚至想修改队列的前端(或结束)变量吗?
感谢您的时间!
解决方案
我将尝试对 Q1、Q2 和 Q3 给出一些快速的答案(但绝不是完整的,您应该研究用于更好地理解的术语)。就像评论所暗示的那样,其余的更适合代码审查。
Q1 - A) 由于引用是常量,编译器能够将文字绑定到参数。思路是,如果函数不能修改它,那么 object*/primitive 是定义还是字面量都无关紧要。如果签名是push(value_type & value)
,那么这将不起作用。此函数期望对允许您修改它的对象/基元的非常量引用。这是没有意义的,因为您不能修改文字,因此是不允许的。
B)是enqueue(Queue const & value)
的将添加深层副本,但该函数不应该获取值的副本。如果是这样,您将复制所有项目 2 次而不是 1 次。该函数enqueue(Queue const value)
(获取一个副本)将首先value
从您给该函数的参数构造一个新队列(请参阅复制构造函数)。然后value
将新元素添加到调用队列的前面,并使用value
. 因此,在构造参数值和将项目添加到调用队列时,每个项目将被复制两次。
Q2 - 如评论中所述,value_type && value
是转发参考或r 值参考。或多或少是对未绑定到l-value的值的引用。这使您能够有效地执行诸如push(MyObject(1, 2, 3))
(MyObject(1, 2, 3)
未绑定到“左值”)或传递所有权之类的事情。(见移动构造函数)
Q3 -const T & front() const
第一个const
是指返回类型(T&),第二个const
是指调用对象(队列)。front
返回对队列中第一个元素的引用。T & front()
使您能够获取第一个元素并通过引用对其进行修改(是的,在某些情况下修改队列的前端很有用)。但是如果 Queue 是常量,那么获取第一个元素并修改它就没有意义了。因此,您为用户提供了在 const Queue's, 上使用的替代方法const T & front() const
。您仍然可以获得对队列前面的引用,但该引用是 const 限定的,因此您无法修改它。根据编译器 -const T & front() const
适用于 const Queue,T & front()
适用于普通 Queue。
推荐阅读
- python-2.7 - 如何在 python 2.7 中重新启动 python?
- java - 使用 JPA 将字符串名称作为 Id
- google-cloud-endpoints - Google Cloud Endpoints 是否仅适用于 REST?
- java - 将 ElasticSearch LowLevelRestClient 的响应映射到 Bean
- swift - 为什么 UINavigationController 子类中需要覆盖 init(rootViewController) 和 init(nibName, bundle)?
- c# - 如何使用/运行在远程连接系统中运行的语音识别 C# 应用程序?
- regex - bash脚本中正则表达式中正数范围的负数
- javascript - 到达页面底部后,如何禁用向后滚动网页?
- html - 如何仅为移动版本创建 div?
- java - Wildfly 10 通过 http 管理 api 列出所有部署的战争工件