我理解指针和引用的语法和一般语义,但是我应该如何决定什么时候在API中使用引用或指针是比较合适的呢?
当然,有些情况需要其中之一(operator++
需要引用参数),但总的来说,我发现我更喜欢使用指针(和常量指针),因为语法很清楚,变量是破坏性传递的。
例如,在以下代码中:
void add_one(int& n) { n += 1; }
void add_one(int* const n) { *n += 1; }
int main() {
int a = 0;
add_one(a); // Not clear that a may be modified
add_one(&a); // 'a' is clearly being passed destructively
}
有了指针,发生了什么事情总是(更)明显,所以对于清晰度很重要的API和类似的东西来说,指针不是比引用更合适吗?这是否意味着引用应该只在必要时使用(例如operator++
)?其中之一是否存在性能方面的问题?
编辑(过时):
除了允许空值和处理原始数组之外,似乎选择取决于个人偏好。我已经接受了下面的答案,即引用Google's C++ Style Guide,因为他们提出了“引用可能会令人困惑,因为它们具有值语法但却具有指针语义”的观点。
由于清理不应该为空的指针参数所需的额外工作(例如,add_one(0)
将在运行时调用指针版本和中断),从可维护性的角度来看,在对象必须存在的地方使用引用是有意义的,尽管失去语法清晰度是一种遗憾。
发布于 2011-08-15 01:14:24
性能完全相同,因为引用是作为指针在内部实现的。因此,您不需要担心这一点。
关于何时使用引用和指针,没有普遍接受的约定。在少数情况下,您必须返回或接受引用(例如,复制构造函数),但除此之外,您可以随心所欲地执行。我遇到的一个相当常见的约定是,当参数必须引用现有对象时使用引用,当空值为ok时使用指针。
一些编码约定(如Google's)规定应该始终使用指针或常量引用,因为引用有一些不明确的语法:它们有引用行为,但值语法。
发布于 2013-02-28 14:48:28
免责声明:除了引用不能为空也不能“反弹”的事实(这意味着他们不能改变它们的别名),这真的是一个品味问题,所以我不会说“这更好”。
也就是说,我不同意你在帖子中的最后一句话,因为我不认为代码在引用时会失去清晰度。在您的示例中,
add_one(&a);
可能比这更清楚
add_one(a);
因为你知道a的值最有可能会改变。另一方面,函数的签名
void add_one(int* const n);
也不太清楚:n是一个整数还是一个数组?有时,您只能访问(文档记录较差的)标头和签名,如
foo(int* const a, int b);
乍一看并不容易理解。
Imho,当不需要(重新)分配或重新绑定(在前面解释的意义上)时,引用就像指针一样好。此外,如果开发人员只对数组使用指针,那么函数签名就不那么含糊了。更不用说运算符的语法在引用时更具可读性了。
发布于 2013-08-28 20:11:58
这不是品味的问题。以下是一些明确的规则。
如果您想在声明变量的作用域中引用静态声明的变量,那么使用C++引用,它将是完全安全的。这同样适用于静态声明的智能指针。通过引用传递参数就是这种用法的一个示例。
如果你想从一个比声明它的作用域更宽的作用域中引用任何东西,那么你应该使用引用计数的智能指针来保证它是完全安全的。
为了语法方便,可以使用引用引用集合中的元素,但这是不安全的;可以随时删除该元素。
若要安全地保留对集合元素的引用,必须使用引用计数的智能指针。
https://stackoverflow.com/questions/7058339
复制相似问题