C++ 参数通过引用传递给指针问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7308384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Argument passing by reference to pointer problem
提问by Raven
Every time I try to compile my code I get error:
每次我尝试编译我的代码时,都会出现错误:
cannot convert parameter 1 from 'int *' to 'int *&'
The test code looks like this:
测试代码如下所示:
void set (int *&val){
*val = 10;
}
int main(){
int myVal;
int *pMyVal = new int;
set(&myVal); // <- this causes trouble
set(pMyVal); // <- however, this doesn't
}
I'd like to call that function in a single shot without creating a pointer somewhere only to pass it. And as pointers don't have constructors, something like this can't be done: set(int*(&myVal));
我想一次性调用该函数,而无需在某处创建指针来传递它。由于指针没有构造函数,因此无法完成以下操作:set(int*(&myVal));
Is there any other way to pass a pointer by reference without needing to create a temporary variable?
有没有其他方法可以通过引用传递指针而无需创建临时变量?
Edit: By the way I know why the code fails to compile (I'm just passing the address which is possibly int and not an actual pointer). The question is how else can it be done.
编辑:顺便说一下,我知道为什么代码无法编译(我只是传递可能是 int 而不是实际指针的地址)。问题是还能怎么做。
回答by Armen Tsirunyan
A reference to non-const cannot bind to an rvalue. The result of the &
operator is an rvalue. Take a look at the difference between lvalues and rvaluesor read a good C++ book.
对非常量的引用不能绑定到右值。&
运算符的结果是一个右值。看看左值和右值之间的区别或阅读一本好的 C++ 书。
Also, in your context, you don't need to pass by reference. The following is OK as well:
此外,在您的上下文中,您不需要通过引用传递。以下也可以:
void set (int *val){
*val = 10;
}
The reference would be needed if you were to do something like this;
如果您要执行此类操作,则需要参考;
void set (int*& val){
val = new int; //notice, you change the value of val, not *val
*val = 10;
}
回答by Kerrek SB
&myval
is an rvalue (of type int*
), because it's a temporary. It's a pointer, but you cannot modify it, because it's just created on the fly. Your function set
however requires a non-const reference, so you cannot pass it a temporary.
&myval
是一个右值(类型int*
),因为它是一个临时的。它是一个指针,但您不能修改它,因为它只是动态创建的。set
但是,您的函数需要非常量引用,因此您不能将其传递给临时对象。
By contrast, pMyVal
is a named variable, thus an lvalue, so it can be passed as a non-constant reference.
相比之下,pMyVal
是一个命名变量,因此是一个左值,因此它可以作为非常量引用传递。
回答by Dave S
The problem is, int*&val
can only be passed an lvalue, which the result of &myVal is not. By changing the signature to void set(int* const& val)
, it's telling the compiler you're not going to change the value of the pointer.
问题是,int*&val
只能传递一个左值,而 &myVal 的结果不是。通过将签名更改为void set(int* const& val)
,它告诉编译器您不会更改指针的值。
However, you normally wouldn't do that, only because if you're not going to change the value of the pointer, then passing the pointer by value is the most straightforward way to pass the value. And if you are going to change the value of the pointer, then you need to create a temporary to receive the result.
但是,您通常不会这样做,只是因为如果您不打算更改指针的值,那么按值传递指针是传递值的最直接方式。如果您要更改指针的值,则需要创建一个临时对象来接收结果。
回答by curious_beast
A very simple example can be found in this place. http://markgodwin.blogspot.de/2009/08/c-reference-to-pointer.html
在这个地方可以找到一个非常简单的例子。 http://markgodwin.blogspot.de/2009/08/c-reference-to-pointer.html
回答by Son Nguyen
You can see the following sample code:
您可以看到以下示例代码:
#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;
}
I installed Cygwin and used g++ to compile the above source code, binary file is out_pointer.exe. Executing out_pointer.exe, output is as follows:
我安装了 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
From the above output, we see
从上面的输出中,我们看到
&ptrNumber = &ptr
So, ptr is alias of ptrNumber. You can modify ptrNumber inside function void change(int*& ptr) by modifying ptr. For example, you can point ptr to another memory location as below:
所以,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;
}
New output:
新输出:
$ ./out_pointer.exe
>>> &ptrNumber = 0x28ac3c
>>> ptrNumber = 0x800102c0
>>> *ptrNumber = 10
==================change(int*& ptr)====================
&ptr = 0x28ac3c
>>> ptr = 0x800102c0
<<< ptr = 0x80048328
=======================================================
<<< &ptrNumber = 0x28ac3c
<<< ptrNumber = 0x80048328
<<< *ptrNumber = 20