通过引用指针传递的参数

时间:2011-09-05 12:53:20

标签: c++ pointers reference arguments

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

无法将参数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而不是实际的指针)。问题是如何做到这一点。

5 个答案:

答案 0 :(得分:13)

对非const的引用不能绑定到右值。 &amp;结果运算符是右值。请查看the difference between lvalues and rvalues或阅读a good C++ book

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

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

如果您要做这样的事情,则需要参考;

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

#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 *&amp; 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