C++ argument passing
好了,我刚开始学习C++,我发现争论的来龙去脉有点让人困惑。我在C++的书中遇到了下面这行。
In C++, passing by reference is accomplished in two ways: using pointers and using references.
号
然后它继续显示一个程序,该程序可以切换两个int值x和y(如下所示)的值。我想知道,在这种情况下,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | //Listing 9.6 Demonstrates passing by reference #include <iostream.h> void swap(int *x, int *y); int main() { int x = 5, y = 10; cout <<"Main. Before swap, x: " << x <<" y:" << y <<" "; swap(&x,&y); cout <<"Main. After swap, x: " << x <<" y:" << y <<" "; return 0; } void swap(int *px, int *py) { int temp; cout <<"Swap. Before swap, *px:" << *px <<" *py:" << *py <<" "; temp = *px; *px = *py; *py = temp; cout <<"Swap. After swap, *px:" << *px <<" *py:" << *py <<" "; } |
抽象层次的完美结合。
最低级别:当按值传递C++指针时,指针值被复制。
更高级别:通常指针指向某个对象,并且该对象在逻辑上通过引用传递。
在C++中传递引用最直接的方式是使用引用参数。在引擎盖下,C++引用可以(在某些情况下)是指针,但是无法访问或确定任何指针值。所以说引用是通过值传递或复制的没有意义,而是我们讨论绑定引用或绑定到引用。
在正确的程序中,引用不能是空引用,这对于作为形参类型的引用来说是一个明显的优势。
另一个好处是,引用
1 | void foo( const std::string& s ) ... |
可以这样称呼
1 | foo("Blah!" ) |
当使用指向&ldquo;实现&rdquo;逻辑传递引用的指针而不是引用时,这是不可能的。
你是对的。函数
1 | void swap(int *x, int *y); |
正在按值接受其参数。因为参数是指针,所以它可以取消引用它们,从而修改它们指向的内存。不过,指针本身(地址)是按值传递的。您可以看到,如果
1 2 3 4 5 6 | int a = 1; int b = 2; int * pa = &a; int * pb = &b; swap(pa, pb); assert((pa == &a) && (pb == &b)); |
尝试添加类似
1 2 | px += 12; py += 17; |
在
在C++中,指针本身就是一个对象。它有一个值(它指向的地址),可以复制或分配不同的值。它也可以通过引用或值传递,就像其他对象一样。
通过引用获取指针的函数如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <iostream> void pointer_by_reference(int * & p) { p = nullptr; } int main() { int a; int * pa = &a; pointer_by_reference(pa); std::cout <<"&a =" << &a <<", pa =" << pa <<" "; } |
可能的输出:
1 | &a = 0x7ffcfdf2e00c, pa = 0 |
如你所见,
这里是按地址调用,因为您正在捕获变量的地址。在引用调用的情况下,我们使用
详细信息检查按引用调用和按指针调用之间的差异
还可以了解C++中指针变量和引用变量之间的区别吗?
基本上有两种参数传递技术。
您的代码实际上是通过引用传递参数。
对于按值调用,当数据传递到过程中的参数时,只有该值对过程的参数可用。因此,对过程中的参数所做的任何更改都不会影响调用例程的变量。
但是通过引用调用,变量的地址对参数可用。换句话说,参数实际上指向与变量相同的位置。因此,更改过程中的参数实际上会更改传递给它的变量。