繁体   English   中英

通过引用指针传递的参数

[英]Argument passing by reference to pointer problem

每次我尝试编译我的代码时都会收到错误:

无法将参数1从'int *'转换为'int *&'

它正在测试代码如下:

void set (int *&val){
   *val = 10;
}

int main(){
   int myVal;
   int *pMyVal = new int;
   set(&myVal); // <- this cause trouble
   set(pMyVal); // <- however this doesn't
}

我想单手调用该函数而不在某处创建指针只是为了传递它。 并且由于指针没有构造函数,因此无法完成此类操作。 set(int*(&myVal)); 有没有其他方法可以通过引用传递指针而无需创建临时变量?

编辑:顺便说一下,我知道为什么代码无法编译(我只是传递地址,可能是int而不是实际的指针)。 问题是如何做到这一点。

对非const的引用不能绑定到右值。 &运算符的结果是rvalue。 看一下左值和右值之间的区别,或者阅读一本好的C ++书

此外,在您的上下文中,您不需要通过引用传递。 以下也可以:

void set (int *val){
   *val = 10;
}

如果你做这样的事情,就需要参考;

void set (int*& val){
   val = new int; //notice, you change the value of val, not *val
   *val = 10;
}

&myval是一个rvalue(类型为int* ),因为它是一个临时的。 它是一个指针,但你不能修改它,因为它只是在运行中创建的。 但是,您的函数set需要非const引用,因此您不能将其临时传递。

相比之下, pMyVal是一个命名变量,因此是一个左值,因此它可以作为非常量引用传递。

在这个地方可以找到一个非常简单的例子。 http://markgodwin.blogspot.de/2009/08/c-reference-to-pointer.html

您可以看到以下示例代码:

#include <iostream>
using namespace std;

void change(int*& ptr) {
    cout << endl;
    cout << "==================change(int*& ptr)====================" << endl;
    cout << "    &ptr = " << &ptr << endl;
    cout << "    ptr  = " << ptr << endl;
    cout << "=======================================================" << endl;
    cout << endl;
    *ptr *= *ptr;
}

int main(void) {
    int* ptrNumber = new int(10);

    cout << endl;
    cout << "&ptrNumber = " << &ptrNumber << endl;
    cout << "ptrNumber = " << ptrNumber << endl;
    cout << ">>> *ptrNumber = " << *ptrNumber << endl;
    change(ptrNumber);
    cout << "<<< *ptrNumber = " << *ptrNumber << endl;
}

我安装了Cygwin并使用g ++编译上面的源代码,二进制文件是out_pointer.exe。 执行out_pointer.exe,输出如下:

$ ./out_pointer.exe

&ptrNumber = 0x28ac3c
ptrNumber = 0x800102c0
>>> *ptrNumber = 10

==================change(int*& ptr)====================
    &ptr = 0x28ac3c
    ptr  = 0x800102c0
=======================================================

<<< *ptrNumber = 100

从上面的输出,我们看到

&ptrNumber = &ptr

所以,ptr是ptrNumber的别名。 您可以通过修改ptr来修改函数void change(int *&ptr)中的ptrNumber。 例如,您可以将ptr指向另一个内存位置,如下所示:

#include <iostream>
using namespace std;

void change(int*& ptr) {
    cout << endl;
    cout << "==================change(int*& ptr)====================" << endl;
    cout << "    &ptr = " << &ptr << endl;
    cout << "    >>> ptr = " << ptr << endl;
    ptr = new int(20);
    cout << "    <<< ptr = " << ptr << endl;
    cout << "=======================================================" << endl;
    cout << endl;
}

int main(void) {
    int* ptrNumber = new int(10);

    cout << endl;
    cout << ">>> &ptrNumber = " << &ptrNumber << endl;
    cout << ">>> ptrNumber = " << ptrNumber << endl;
    cout << ">>> *ptrNumber = " << *ptrNumber << endl;
    change(ptrNumber);
    cout << "<<< &ptrNumber = " << &ptrNumber << endl;
    cout << "<<< ptrNumber = " << ptrNumber << endl;
    cout << "<<< *ptrNumber = " << *ptrNumber << endl;
}

新产出:

$ ./out_pointer.exe

>>> &ptrNumber = 0x28ac3c
>>> ptrNumber = 0x800102c0
>>> *ptrNumber = 10

==================change(int*& ptr)====================
    &ptr = 0x28ac3c
    >>> ptr = 0x800102c0
    <<< ptr = 0x80048328
=======================================================

<<< &ptrNumber = 0x28ac3c
<<< ptrNumber = 0x80048328
<<< *ptrNumber = 20

问题是, int*&val只能传递一个左值,而myVal的结果不是。 通过将签名更改为void set(int* const& val) ,它告诉编译器您不会更改指针的值。

但是,您通常不会这样做,只是因为如果您不打算更改指针的值,那么按值传递指针是传递该值的最直接的方法。 如果要更改指针的值,则需要创建临时值以接收结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM