在说这将是一个重复的问题和downvote(之前发生过)之前,我搜索并发现没有任何相似之处。
我和许多其他人一样,正在尝试学习C ++参考变量的用法并将它们与指针联系起来。我发现制作表格更容易,我需要知道是否需要修改它。
int *n int n int &n caller/local
void foo(int *n) n &n &n caller
void foo(int n) *n n n local
void foo(int &n) *n n n caller
该表希望反映所有合法传递的参数。
[1,1]: passing by reference (trivial)
[1,2]: passing by reference
[1,3(1)]: passing by reference, an is an address(?)
[1,3(2)]: passing by reference, as n is used as alias(?)
[2,1]: passing by value, as dereferencing
[2,2]: passing by value (trivial)
[2,3(1)]: passing by value, using value of n (where n is an alias)
[2,3(2)]: passing by value (dereferencing n, which is an address)
[3,1(1)]: passing by reference, as foo accepts address
[3,1(2)]: passing by reference, reference of value at address n
[3,2(1)]: passing by reference (trivial)
[3,2(2)]: passing by reference, as foo accepts address or reference
[3,3]: passing by reference (trivial, as argument matches parameter exactly)
答案 0 :(得分:5)
功能
void foo(int& n);
不接受地址(指针),也不接受文字。
所以你不能把它称为
int a = ...;
foo(&a); // Trying to pass a pointer to a function not taking a pointer
或
foo(1); // Passing R-value is not allowed, you can't have a reference to a literal value
但是有一个例外,如果你有一个恒定的引用,比如
int foo(const int& n);
然后允许使用文字值,因为那时引用的值不能改变。
同样适用于
void foo(int* n);
你必须传递一个指针。
例如:
int a = ...;
int& ra = a; // ra references a
foo(&a); // OK
foo(&ra); // OK
foo(a); // Fail, a is not a pointer
foo(ra); // Fail, ra is not a pointer
foo(1); // Fail, the literal 1 is not a pointer
最后一次:
void foo(int n);
举例:
int a = ...;
int& ra = a; // ra references a
int* pa = &a; // pa points to a
foo(a); // OK, the value of a is copied
foo(ra); // OK, the value of the referenced variable is copied
foo(*pa); // OK, dereferences the pointer, and the value is copied
foo(pa); // Fail, passing a pointer to a function not expecting a pointer
foo(1); // OK, the literal value 1 is copied
答案 1 :(得分:1)
operator*
和operator&
operator&
(一元)和operator*
(一元)都可以重载。
这意味着,如果n
是类型type
,则*n
可以包含任何形式,包括但不限于type*
,type&
,type
。
一个例子(愚蠢,但仍然是一个有效的例子)将是:
struct type {
int x;
};
int& operator&(type& t) {
return t.x;
}
您还可以拥有无限数量的指针间接。在这种情况下,*n
,**n
,***n
也可能会产生Type*
以及Type&
。
举个例子,给出两个函数:
void func_ptr(int*) {}
void func_ref(int&) {}
以及以下对象:
int a;
int* b = &a;
int** c = &b;
int*** d = &c;
然后,以下任何一项都有效:
func_ptr(b);
func_ptr(*c);
func_ptr(**d);
func_ref(*b);
func_ref(**c);
func_ref(***d);
表格和说明是否正确?表格中是否有任何情况(除了像*& n,指针指针等派生的那些)?
因此,该表不仅不完整,而且不可能包含所有可能的情况。
答案 2 :(得分:1)
也许我错误地解释了您的表格,但假设您已经在左侧的三个函数中,并希望获得int*
到n
,请使用{{1并绑定对分别通过n
访问的int
值的引用:
原始表格
n
鉴于左侧的功能签名,您有以下错误:
在 int *n int n int &n
void foo(int *n) n &n n/&n
void foo(int n) *n n n/*n
void foo(int &n) n/*n n/&n n
:
foo(int* n)
int
不 *n
&n
绑定到int&
在*n
foo(int n)
的指针n
不 &n
*n
绑定到int&
n
, 不 n
*n
是本地的,已复制且与来电者的n
在n
:
foo(int& n)
您想要n
而非 &n
或n
*n
您只需要n
不 / 从不 { {1}} 所以,我写这样的表格(我已经为n
的地址添加了列,以及&n
是来自调用上下文的n
还是本地副本)
建议更正的表格
n
我不相信这样的表在澄清引用和指针的作用方面有很多用处。
更新:您的评论解释说您希望表格传达"传递表格",我将其视为n
来电者所需的代码。正确的表应该是:
int* int int& n2 = ... int* p = ... caller/local
void foo(int* p_n) p_n *p_n *p_n p_n caller
void foo(int n) &n n n &n local
void foo(int& n) &n n n &n caller