我正在尝试将C ++引用与指针相关联

时间:2014-06-27 11:14:17

标签: c++ pointers reference

在说这将是一个重复的问题和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)  
  1. 表格和说明是否正确?
  2. 表中是否还有任何情况(除了像*& n,指针指针等派生的那些)?

3 个答案:

答案 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;
}

Live demo

的间接

您还可以拥有无​​限数量的指针间接。在这种情况下,*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);

Live demo

结论

  

表格和说明是否正确?表格中是否有任何情况(除了像*& 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 而非 &nn
  • 的指针
  • 使用*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