在 C++ 中传递对指针的引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/823426/
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
Passing references to pointers in C++
提问by Alex
As far as I can tell, there's no reason I shouldn't be allowed to pass a reference to a pointer in C++. However, my attempts to do so are failing, and I have no idea why.
据我所知,没有理由不允许我在 C++ 中传递对指针的引用。但是,我这样做的尝试失败了,我不知道为什么。
This is what I'm doing:
这就是我正在做的:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
And I'm getting this error:
我收到此错误:
cannot convert parameter 1 from 'std::string *' to 'std::string *&'
无法将参数 1 从“std::string *”转换为“std::string *&”
采纳答案by Chris
Your function expects a reference to an actual string pointer in the calling scope, not an anonymous string pointer. Thus:
您的函数需要对调用范围内的实际字符串指针的引用,而不是对匿名字符串指针的引用。因此:
string s;
string* _s = &s;
myfunc(_s);
should compile just fine.
应该编译就好了。
However, this is only useful if you intend to modify the pointer you pass to the function. If you intend to modify the string itself you should use a reference to the string as Sake suggested. With that in mind it should be more obvious why the compiler complains about you original code. In your code the pointer is created 'on the fly', modifying that pointer would have no consequence and that is not what is intended. The idea of a reference (vs. a pointer) is that a reference always points to an actual object.
但是,这仅在您打算修改传递给函数的指针时才有用。如果您打算修改字符串本身,您应该按照 Sake 的建议使用对字符串的引用。考虑到这一点,编译器为什么抱怨你的原始代码应该更明显了。在您的代码中,指针是“动态”创建的,修改该指针不会产生任何后果,这不是预期的。引用(相对于指针)的想法是引用始终指向实际对象。
回答by Michael Burr
The problem is that you're trying to bind a temporary to the reference, which C++ doesn't allow unless the reference is const
.
问题是您试图将临时对象绑定到引用,除非引用是const
.
So you can do one of either the following:
因此,您可以执行以下任一操作:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
void myfunc2(string* const& val)
{
// Do stuff to the string pointer
}
int main()
// sometime later
{
// ...
string s;
string* ps = &s;
myfunc( ps); // OK because ps is not a temporary
myfunc2( &s); // OK because the parameter is a const&
// ...
return 0;
}
回答by aJ.
Change it to:
将其更改为:
std::string s;
std::string* pS = &s;
myfunc(pS);
EDIT:
编辑:
This is called ref-to-pointer
and you cannot pass temporary address as a reference to function. ( unless it is const reference
).
这被调用ref-to-pointer
,您不能将临时地址作为对函数的引用传递。(除非是const reference
)。
Though, I have shown std::string* pS = &s;
(pointer to a local variable), its typical usage would be :
when you want the callee to change the pointer itself, not the object to which it points. For example, a function that allocates memory and assigns the address of the memory block it allocated to its argument must take a reference to a pointer, or a pointer to pointer:
不过,我已经展示了std::string* pS = &s;
(指向局部变量的指针),它的典型用法是:当您希望被调用者更改指针本身而不是它指向的对象时。例如,一个分配内存并将其分配给其参数的内存块地址的函数必须引用一个指针,或一个指向指针的指针:
void myfunc(string*& val)
{
//val is valid even after function call
val = new std::string("Test");
}
回答by n0rd
&s
produces temporary pointer to string and you can't make reference to temporary object.
&s
产生指向字符串的临时指针,您不能引用临时对象。
回答by Sake
Try:
尝试:
void myfunc(string& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(s);
// ...
}
or
或者
void myfunc(string* val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
回答by Ari
EDIT: I experimented some, and discovered thing are a bit subtler than I thought. Here's what I now think is an accurate answer.
编辑:我尝试了一些,发现事情比我想象的要微妙一些。这是我现在认为的准确答案。
&s
is not an lvalue so you cannot create a reference to it unless the type of the reference is reference to const
. So for example, you cannot do
&s
不是左值,因此您无法创建对它的引用,除非引用的类型是对 的引用const
。所以例如,你不能做
string * &r = &s;
but you can do
但你可以
string * const &r = &s;
If you put a similar declaration in the function header, it will work.
如果您在函数头中放置类似的声明,它将起作用。
void myfunc(string * const &a) { ... }
There is another issue, namely, temporaries. The rule is that you can get a reference to a temporary only if it is const
. So in this case one might argue that &s is a temporary, and so must be declared const
in the function prototype. From a practical point of view it makes no difference in this case. (It's either an rvalue or a temporary. Either way, the same rule applies.) However, strictly speaking, I think it is not a temporary but an rvalue. I wonder if there is a way to distinguish between the two. (Perhaps it is simply defined that all temporaries are rvalues, and all non-lvalues are temporaries. I'm not an expert on the standard.)
还有一个问题,即临时性。规则是,只有当它是 时,您才能获得对临时文件的引用const
。所以在这种情况下,人们可能会争辩说 &s 是一个临时的,因此必须const
在函数原型中声明。从实际的角度来看,在这种情况下它没有区别。(它要么是右值,要么是临时值。无论哪种方式,都适用相同的规则。)但是,严格来说,我认为它不是临时值,而是右值。我想知道是否有办法区分两者。(也许只是简单地定义了所有临时值都是右值,所有非左值都是临时值。我不是该标准的专家。)
That being said, your problem is probably at a higher level. Why do you want a reference to the address of s
? If you want a reference to a pointer to s
, you need to define a pointer as in
话虽如此,您的问题可能处于更高的水平。为什么要引用 的地址s
?如果您想引用指向 的指针s
,则需要定义一个指针,如
string *p = &s;
myfunc(p);
If you want a reference to s
or a pointer to s
, do the straightforward thing.
如果您想要对 的引用s
或指针s
,请做简单的事情。
回答by Mohd
I have just made use of a reference to a pointer to make all the pointers in a deleted binary tree except the root safe. To make the pointer safe we just have to set it to 0. I could not make the function that deletes the tree (keeping only the root) to accept a ref to a pointer since I am using the root (this pointer) as the first input to traverse left and right.
我刚刚使用对指针的引用来创建已删除二叉树中除根安全之外的所有指针。为了使指针安全,我们只需将其设置为 0。我无法使删除树的函数(仅保留根)接受对指针的引用,因为我使用根(此指针)作为第一个输入以左右遍历。
void BinTree::safe_tree(BinTree * &vertex ) {
if ( vertex!=0 ) { // base case
safe_tree(vertex->left); // left subtree.
safe_tree(vertex->right); // right subtree.
// delete vertex; // using this delete causes an error, since they were deleted on the fly using inorder_LVR. If inorder_LVR does not perform delete to the nodes, then, use delete vertex;
vertex=0; // making a safe pointer
}
} // end in
Bottom line, a reference to a pointer is invalid when the formal parameter is the (this) pointer.
底线,当形式参数是(this)指针时,对指针的引用是无效的。
回答by not-a-user
Welcome to C++11 and rvalue references:
欢迎使用 C++11 和右值参考:
#include <cassert>
#include <string>
using std::string;
void myfunc(string*&& val)
{
assert(&val);
assert(val);
assert(val->c_str());
// Do stuff to the string pointer
}
// sometime later
int main () {
// ...
string s;
myfunc(&s);
// ...
}
Now you have access to the value of the pointer (referred to by val
), which is the address of the string.
现在您可以访问指针的值(由 引用val
),它是字符串的地址。
You can modify the pointer, and no one will care. That is one aspect of what an rvalue is in the first place.
你可以修改指针,没有人会在意。这是右值首先是什么的一个方面。
Be careful: The value of the pointer is only valid until myfunc()
returns. At last, its a temporary.
注意:指针的值仅在myfunc()
返回之前有效。最后,它是一个临时的。
回答by Robert Gould
I know that it's posible to pass references of pointers, I did it last week, but I can't remember what the syntax was, as your code looks correct to my brain right now. However another option is to use pointers of pointers:
我知道可以传递指针的引用,我上周做到了,但我不记得语法是什么,因为你的代码现在对我的大脑来说是正确的。然而,另一种选择是使用指针的指针:
Myfunc(String** s)
回答by Shashikiran
myfunc("string*& val") this itself doesn't make any sense. "string*& val" implies "string val",* and & cancels each other. Finally one can not pas string variable to a function("string val"). Only basic data types can be passed to a function, for other data types need to pass as pointer or reference. You can have either string& val or string* val to a function.
myfunc("string*& val") 这本身没有任何意义。“string*& val”暗示“string val”,*和&相互抵消。最后,不能将字符串变量传递给函数(“string val”)。只有基本数据类型可以传递给函数,其他数据类型需要作为指针或引用传递。您可以将 string& val 或 string* val 用于函数。