通过引用传递参数到指针问题

发布于 2024-12-02 21:36:49 字数 541 浏览 0 评论 0原文

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

cannot convert parameter 1 from 'int *' to 'int *&'

测试代码如下所示:

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
}

我想一次性调用该函数,而无需在某处创建指针只是为了传递它。由于指针没有构造函数,因此无法完成这样的操作: set(int*(&myVal));

有没有其他方法可以通过引用传递指针而无需创建临时变量?

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

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));

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

放赐 2024-12-09 21:36:49

对非常量的引用不能绑定到右值。 & 运算符的结果是右值。查看左值和右值之间的区别或阅读一本很好的 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;
}

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 rvalues or read a good C++ book.

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;
}
锦上情书 2024-12-09 21:36:49

&myval 是一个右值(int* 类型),因为它是临时的。它是一个指针,但您无法修改它,因为它只是动态创建的。然而,您的函数 set 需要一个非常量引用,因此您不能将其传递为临时引用。

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

&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.

By contrast, pMyVal is a named variable, thus an lvalue, so it can be passed as a non-constant reference.

魔法唧唧 2024-12-09 21:36:49

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

A very simple example can be found in this place.
http://markgodwin.blogspot.de/2009/08/c-reference-to-pointer.html

够钟 2024-12-09 21:36:49

你可以看到下面的示例代码:

#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

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:

$ ./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:

#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
同展鸳鸯锦 2024-12-09 21:36:49

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

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

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文