[英]Passing references to pointers in C++
据我所知,没有理由不允许我在C ++中传递对指针的引用。 但是,我这样做的尝试失败了,我不知道为什么。
这就是我正在做的事情:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
我收到这个错误:
无法将参数1从'std :: string *'转换为'std :: string *&'
您的函数需要引用调用范围中的实际字符串指针,而不是匿名字符串指针。 从而:
string s;
string* _s = &s;
myfunc(_s);
应该编译得很好。
但是,这仅在您打算修改传递给函数的指针时才有用。 如果您打算修改字符串本身,您应该使用Sake建议的字符串引用。 考虑到这一点,编译器抱怨原始代码的原因应该更加明显。 在你的代码中,指针是“动态”创建的,修改指针没有任何后果,这不是预期的。 引用(与指针相对)的想法是引用始终指向实际对象。
问题是你试图将临时绑定到引用,除非引用是const
否则C ++不允许。
所以您可以执行以下任一操作之一:
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;
}
将其更改为:
std::string s;
std::string* pS = &s;
myfunc(pS);
编辑:
这称为ref-to-pointer
,您不能将临时地址作为函数的引用传递。 (除非是const reference
)。
虽然,我已经显示了std::string* pS = &s;
(指向局部变量的指针),它的典型用法是:当你希望被调用者改变指针本身时,而不是它指向的对象。 例如,一个分配内存并分配它分配给其参数的内存块地址的函数必须引用指针或指针指针:
void myfunc(string*& val)
{
//val is valid even after function call
val = new std::string("Test");
}
&s
生成临时指向字符串的指针,您无法引用临时对象。
尝试:
void myfunc(string& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(s);
// ...
}
要么
void myfunc(string* val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
编辑:我试验了一些,并发现事情比我想象的更微妙。 以下是我现在认为的准确答案。
&s
不是左值,因此除非引用的类型是对const
的引用,否则无法创建对它的引用。 所以例如,你做不到
string * &r = &s;
但你可以做到
string * const &r = &s;
如果在函数头中放入类似的声明,它将起作用。
void myfunc(string * const &a) { ... }
还有另一个问题,即临时问题。 规则是只有当它是const
时才可以获得对临时的引用。 所以在这种情况下,有人可能认为&s是临时的,因此必须在函数原型中声明为const
。 从实际的角度来看,这种情况没有区别。 (无论是左值还是临时值。无论哪种方式,同样的规则都适用。)但是,严格地说,我认为这不是暂时的,而是一个左值。 我想知道是否有办法区分这两者。 (也许只是定义所有临时值都是rvalues,所有非左值都是临时值。我不是标准专家。)
话虽这么说,你的问题可能在更高的水平。 为什么要引用s
的地址? 如果要引用指向s
的指针,则需要将指针定义为
string *p = &s;
myfunc(p);
如果你想参考s
或指向s
,做简单的事情。
我刚刚使用了对指针的引用,以便在除了root安全之外的已删除二进制树中生成所有指针。 为了使指针安全,我们只需将其设置为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
底线,当形参数是(this)指针时,对指针的引用无效。
欢迎使用C ++ 11和rvalue引用:
#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);
// ...
}
现在您可以访问指针的值(由val
引用),这是字符串的地址。
你可以修改指针,没人会关心。 这是首要问题的一个方面。
注意:指针的值仅在myfunc()
返回之前有效。 最后,它是暂时的。
我知道传递指针的引用是可行的,我上周做过,但是我不记得语法是什么,因为你的代码现在对我的大脑来说是正确的。 然而另一个选择是使用指针指针:
Myfunc(String** s)
myfunc(“string *&val”)这本身没有任何意义。 “string *&val”表示“string val”,*和&相互抵消。 最后一个不能将字符串变量传递给函数(“string val”)。 只有基本数据类型可以传递给函数,因为其他数据类型需要作为指针或引用传递。 你可以在一个函数中使用string&val或string * val。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.