[英]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.