- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在 C++ Primer 第五版中,它说:
int f(int){ /* can write to parameter */}
int f(const int){ /* cannot write to parameter */}
这两个函数无法区分。但是如您所知,这两个函数在更新参数的方式上确实存在差异。
谁能给我解释一下?
编辑
我想我没有很好地解释我的问题。我真正关心的是为什么 C++ 不允许这两个函数同时作为不同的函数,因为它们在“是否可以写入参数”方面确实不同。直觉上应该是!
编辑
按值传递的本质其实是通过将参数值复制到参数值来传递。即使对于引用 和指针,您复制的值是地址。从调用者的角度来看,无论是 const 还是 non-const 传递给函数都不会影响复制到参数的值(当然还有类型)。
top-level const 和low-level const 之间的区别在复制对象时很重要。更具体地说,复制对象时忽略顶级常量(不是低级常量),因为复制不会影响复制的对象。复制到或复制自的对象是否为 const 并不重要。
所以对于调用者来说,区分它们是没有必要的。从函数的角度来看,顶级 const 参数可能不会影响函数的接口(interface)和/或功能。这两个函数实际上完成的是同一件事。为什么要费心实现两个拷贝?
最佳答案
allow these two functions simultaneously as different function since they are really different as to "whether parameter can be written or not". Intuitively, it should be!
函数的重载是基于调用者提供的参数。在这里,调用者确实可以提供 const
或非 const
值,但从逻辑上讲,它对被调用函数提供的功能应该没有影响。考虑:
f(3);
int x = 1 + 2;
f(x);
如果 f()
在每一种情况下做不同的事情,那将是非常困惑的!这段调用 f()
的代码的程序员可以对相同的行为有合理的期望,可以自由地添加或删除传递参数的变量,而不会使程序无效。这种安全、理智的行为是您想要证明异常(exception)的出发点,而且确实有一个 - 当函数重载时,行为可以改变 ala:
void f(const int&) { ... }
void f(int&) { ... }
所以,我猜这就是您发现的不直观之处:C++ 为非引用提供了比引用更多的“安全性”(通过仅支持单一实现来强制执行一致的行为)。。 p>
我能想到的原因是:
const&
参数的生命周期更长时,他们可以选择最佳实现。例如,在下面的代码中,返回对 F
中的 T
成员的引用可能会更快,但是如果 F
是一个临时的 (如果编译器匹配 const F&
) 则可能需要按值返回。这仍然非常危险,因为调用者必须知道返回的引用仅在参数存在时才有效。T f(const F&); T& f(F&); // return type could be by const& if more appropriate
const
-ness through function calls as in:const T& f(const F&); T& f(F&);
Here, some (presumably F
member-) variable of type T
is being exposed as const
or non-const
based on the const
-ness of the parameter when f()
is called. This type of interface might be chosen when wishing to extend a class with non-member functions (to keep the class minimalist, or when writing templates/algos usable on many classes), but the idea is similar to const
member functions like vector::operator[]()
, where you want v[0] = 3
allowed on a non-const
vector but not a const
one.
When values are accepted by value they go out of scope as the function returns, so there's no valid scenario involving returning a reference to part of the parameter and wanting to propagate its qualifiers.
Given the rules for references, you can use them to get the kind of behaviour you want - you just need to be careful not to modify the by-non-const-reference parameter accidentally, so might want to adopt a practice like the following for the non-const parameters:
T f(F& x_ref)
{
F x = x_ref; // or const F is you won't modify it
...use x for safety...
}
除了为什么语言禁止基于按值参数的 const
特性的重载之外,还有一个问题是为什么它不坚持 的一致性声明和定义中的 const
-ness。
对于 f(const int)
/f(int)
... 如果您在头文件中声明一个函数,那么最好不要包含 const
限定符,即使稍后在实现文件中定义也会有它。这是因为在维护期间,程序员可能希望删除限定符......从 header 中删除它可能会触发客户端代码的无意义重新编译,因此最好不要坚持让它们保持同步 - 事实上这就是编译器不这样做的原因如果它们不同,则不会产生错误。如果您只是在函数定义中添加或删除 const
,那么它接近代码读者在分析函数行为时可能关心常量的实现。如果您在头文件和实现文件中都包含 const
,那么程序员希望将其设为非 const
并忘记或决定不更新头文件以避免客户端重新编译,那么它比其他方式更危险,因为程序员在尝试分析导致对函数行为的错误推理的当前实现代码时,可能会考虑 header 中的 const
版本。这都是一个非常微妙的维护问题 - 只与商业编程真正相关 - 但这是不在界面中使用 const
指南的基础。此外,从接口(interface)中省略它更简洁,这对于阅读您的 API 的客户端程序员来说更好。
关于c++ - 顶级 const 不影响函数签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17208570/
这是一个非常笼统的问题,我希望我能答对。 我正在研究 SSL/TLS 重新协商并已阅读了一些内容。这是我从阅读中了解到的内容: 从 SSL/TLS 重新协商的角度来看,客户端分为两个主要组,打补丁的和
第一个屏幕是艺术的细节。当我向上滚动时,标题将是 alpha。我点击另一个“艺术”到另一个细节 UI,然后按回到 Previous UI。之前的UI标题是黑色的,怎么变透明了。 布局:
想知道 mv 对基表的影响。它会减慢基表的速度吗?它什么时候开始写入 mv,就像同时写入基表和 mv 一样? 如果我有 local_quorum 的 CL 且 RF=3,客户端是否必须等到写入 mv
似乎在任何地方都找不到太多关于此问题的帮助,所以我想我会在这里尝试。 我正在尝试制作一个简单的 for 循环,当我将鼠标悬停在 html 卡上时,它会隐藏卡中的一些文本。该卡有一个简单的名字和姓氏,我
我有一个程序每帧运行 tick() 方法。我希望一个对象根据设定的重力常数下落,因此我创建了一个 Ball 对象,该对象会将其位置更新为前一帧的位置减去 y 速度。每个刻度 y 速度都会减少重力常数。
我的 KeyHandler 在这里: private void KeyHandler(java.awt.event.KeyEvent evt) {
我有一个方法,其中使用了很多其他类,包括链接列表、队列和堆栈。在我的方法中,我有一个 for 循环,我想在其中弹出堆栈(方便地命名为 s)并将队列(方便地命名为 q)出队到 s1 和 q1。由于某种原
我有一个 JTree 节点数组和另一个自定义对象的相应数组。 我想要什么:当选择 JTree 的节点时,相应对象(其数组中索引与节点数组中所选节点索引相同的对象)的字段填充 JLabels。 我被困在
我知道浏览器完成了处理客户端脚本(Javascript、JQuery 等)的所有工作,但想知道在性能方面是否还有其他重要因素(网络速度、客户端计算机速度、服务器环境) 如果它完全依赖于浏览器(类型和版
我有一个 Android 服务在后台运行,它将使用以下代码: while(true) { ServerSocket server = new ServerSocket(1234); Socke
对JQM有以下疑惑: 1.如果我们在单独的 html 文件中使用重复的 id,对 jquery mobile 有什么影响。 假设我们在单独的 html 文件中有重复的 id,但如果我们不使用该 id
我正在尝试更新两个(inventory、sold)MySQL 表的表库存。 假设我们正在处理的 sku 是 BT888-16 UPDATE inventory JOIN sold ON invento
我使用这种方法来更改我的表格单元格值, 它在 jtable 上改变但在文本文件上没有改变! public class user_AllBooks extends AbstractTableModel
我想在向表中插入数据时创建一个 MYSQL 存储过程,数据也会被插入到其他服务器表中。 我知道这在 ORACLE 数据库中是可能的,但我不知道它是否适用于 MYSQL。 有什么办法吗? 最佳答案 是的
我在 css 方面非常糟糕,只能靠 SO 答案来解决 - 但是我找不到针对这个特定问题的任何解释。 我有一个表单,其中包含一个 textarea 和一个 button(input/submit),仅此
我在一个元素上有动画,但它的移动也会影响 sibling 。如何在不影响兄弟元素的情况下仅在元素上使用动画? 问题示例: function animateSearch() { $('.glyph
我试图在我的 ViewController 中的 UIView 的所有四个边上建立一个阴影 — 在我通过 Xcode 向 UIView 添加约束之前,它工作得很好。我怎样才能使 UIView 的阴影显
自从我使用 JavaScript 以来已经有一段时间了 - 在获得证书之后我开始学习 Perl 并从那时起就一直使用它。我只是想重新开始使用 JS,我已经写了这个,我想说的是,这是一个简单的小脚本,可
我正在处理一个 HTML 元素,我添加了一个复选框,选中后会高亮显示所有文本输入字段。唯一的问题是一些输入字段在表格内,出于某种原因我无法用我的代码影响它们。任何帮助将不胜感激。 相关代码: HTML
我为 String 类创建了一个小扩展,以便方便地从中删除字符。这是它的样子: mutating func drop(characters chars: [String]) { for c i
我是一名优秀的程序员,十分优秀!