void foo( int& i );
是不允许的。这是有原因的吗,还是只是规范的一部分?据我所知,引用通常被实现为指针。在C++中,void foo( int* i )
和void foo( int& i )
之间是否有任何功能上的区别(而非语法/语义上的区别)?因为引用是C++的一个特性。
引用仅仅是指针的语法糖。它们的实现是相同的,但它们隐藏了被调用函数可能修改变量的事实。它们唯一真正起重要作用的时间是使其他C++特性成为可能 - 操作符重载就是其中之一 - 根据您的观点,这些也可能是语法糖。
const
引用是可以的,因为它就像传值一样高效,但允许 swap(a, b)
而不是 swap(&a, &b)
明显是一个设计上的失误。C# 使用 ref
和 out
关键字解决了这个问题。 - dan04foo
必须检查它是否被调用为foo((int*)0)
,当它不能检查它是否被调用为foo((int*)1)
或其他数十亿个可能的无效指针值?除非函数的文档明确说明它接受某些无效的指针值并赋予它们特殊含义,否则调用此类函数并传递空指针参数的代码编写者是负责引发UB的人。 - R.. GitHub STOP HELPING ICE&
运算符只有两个含义:
操作数的地址(一元运算符)
按位与运算符(二元运算符)
所以int &i;
不是C语言中有效的声明。
int &i;
也不是一个有效的“声明”! - André Caron对于函数参数而言,指针和引用之间的区别并不是很大的问题。但在许多情况下(例如成员变量),使用引用会严重限制您可以做的事情,因为它不能重新绑定。
C语言中没有引用(References)的概念。但是,C语言有类似于通过引用传递可变参数的机制。例如:
int foo(int in, int *out) { return (*out)++ + in; }
// ...
int x = 1; int y = 2;
x = foo(x, &y);
// x == y == 3.
然而,在更复杂的foo()函数中,很容易忘记在每次使用时对"out"进行解引用。C++中的引用允许更平滑的语法来表示闭包的可变成员。在两种语言中,这可能会使编译器优化受到干扰,因为有多个符号引用同一存储空间。(考虑"foo(x,x)"。现在不确定"++"是仅作用于"*out"还是同时作用于"in",因为两个使用之间没有序列点,并且增量只需要在左表达式的值被获取后的某个时间发生。)
当一个函数的形式为"T &foo(T &)"时,复制省略会变得更加令人兴奋,编译器知道一个临时对象正在进入和离开,并且编译器可以推断出结果可以直接在参数的位置上构造。然后,在编译中不需要编译任何关于临时对象的复制或结果的输出。foo()可以被编译以从某个封闭的堆栈帧获取其参数,并将其结果直接写入某个封闭的堆栈帧。
最近有一篇关于复制省略的文章(惊喜),在现代编译器中,如果你通过值传递,它甚至可以工作得更好(以及C++0x中的右值引用将如何帮助编译器跳过更多无意义的复制),请参见http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/。
void*
强制转换为任何指针类型。在C ++中,这些转换的需求很少,错误也很少发生。 当发生错误时,我希望使用static_cast
进行更正。 这些转换并不是无用的,因为它们标志着程序的弱点。 这一切都关乎强类型安全。 - paercebal