在我的理解中,
void bar(int &x) { ... }
似乎意味着通过x
引用传递。但是在 C++ 中,已经有指针等。那么有什么区别
void bar(int *x) { ... }
// then call by
bar(&x);
除了它更长的事实......我还注意到如果我使用第二种方法,我需要使用->
而不是.
如果我传入一个struct
......为什么?
在我的理解中,
void bar(int &x) { ... }
似乎意味着通过x
引用传递。但是在 C++ 中,已经有指针等。那么有什么区别
void bar(int *x) { ... }
// then call by
bar(&x);
除了它更长的事实......我还注意到如果我使用第二种方法,我需要使用->
而不是.
如果我传入一个struct
......为什么?
Stroustrup 给出对 C++ 的引用的原因是运算符重载。
http://www.stroustrup.com/bs_faq2.html#pointers-and-references
在您的示例函数中,用户是否必须调用它(因为它需要一个指针)或可以调用它(因为它需要一个引用)bar
都没有什么大不了的。至少,C 程序员认为不是。bar(&x)
bar(x)
然而,当 C++ 中添加运算符重载时,Stroustrup 认为使用带指针的重载运算符非常不雅(用他的话来说“丑陋”)。
引用在功能上比指针有一些优势,例如临时对象可以绑定到 const 引用,但您不能将&
运算符应用于它。因此,与通过指针传递到常量的等效函数相比,传递常量引用函数有时会为调用者节省一行代码(以创建变量)。
出于这个原因,一个可能的约定是当您的函数计划将地址存储在某处以供将来使用时,它返回时接受一个指针,并在它没有时接受一个引用。它不会阻止创建悬空指针/引用的所有可能方法,但它会捕获一个大的。但是,在编写函数式代码时,它确实会产生不幸的后果,所以它并不适合所有人。
我还注意到,如果我使用第二种方法,我需要使用 -> 而不是 . 如果我传入一个结构......为什么?
它只是从 C. 继承的语法.
来访问结构->
的成员,通过指向结构的指针来访问成员。在 C 语言中,您只能->
与 LHS 上的指针一起使用,而永远不能与 LHS 上的指针一起使用.
。所以对不同的符号没有严格的要求,它只是有助于使代码更具可读性以具有提醒。例如,如果.
两者使用相同的符号,则(*ptr).member
表示相同的意思ptr.member
,这可能会造成混淆。
在 C++ 中,这种差异对语言变得有用。您可以为类类型重载operator->
,例如智能指针。但是类类型可以使用.
. 所以some_smart_ptr->get();
意味着“get()
在智能指针的引用上调用函数”,而some_smart_ptr.get()
意味着“get()
在智能指针上调用函数”。
A reference is a basically pointer with a constant address, so it has the same effect as calling by address. It's mainly a difference of syntax: calling by reference is more convenient since from the call site it's as if you were calling by value (except you have to be careful with temporaries).