[英]Am I initializing my C++ reference variables correctly?
我試過谷歌這個問題,我找不到任何我認為相關的東西。 所以我一定在尋找錯誤的東西; 盡管如此,我還是很欣賞一些建議......
Foobar &foobar = *new Foobar(someArg, anotherArg);
它只是我還是看起來很臭?
我知道new
關鍵字設計用於指針(如此):
Foobar *foobar = new Foobar(someArg, anotherArg);
但是,如果您不需要該實例上的指針,並且您想使用引用呢? 或者,您是否需要顯式初始化它(很像局部變量); 如果是這種情況,如果我想用參數初始化怎么辦?
以下不起作用(除非我做錯了):
// the last argument is of type: int
Foobar &foobar(someArg, anotherArg);
...給出編譯器錯誤:
初始化表達式列表作為復合表達式處理從'int'類型的臨時表中無效初始化類型'Foobar&'的非const引用
而且這似乎不起作用:
Foobar &foobar = Foobar(someArg, anotherArg);
...給出編譯器錯誤:
錯誤:從'Foobar'類型的臨時類型'Foobar&'類型的非const引用無效初始化
請記住我正在返回此值,因此我不想使用局部變量; 我想在堆上使用一個值,而不是堆棧:
Foobar &helloWorld()
{
Foobar &foobar = *new Foobar(someArg, anotherArg);
foobar.HelloWorld();
return foobar;
}
我應該只使用指針,還是完全有效?
為什么你認為你需要使用新的和引用? 為什么不:
Foobar foobar(someArg, anotherArg);
對於您的函數 - 返回一個值:
Foobar helloWorld()
{
Foobar foobar(someArg, anotherArg);
foobar.HelloWorld();
return foobar;
}
或指針:
Foobar * helloWorld()
{
Foobar * foobar = new Foobar(someArg, anotherArg);
foobar->HelloWorld();
return foobar;
}
如果這樣做 - 調用者負責在某個時刻刪除分配的對象。
從非成員函數返回的地方通常不能合理地使用引用,因為您想要引用的內容通常不再存在。
是的,那很臭!
如果你是'new'的東西,請將它指定給指針(或智能指針類型),因為它需要再次刪除以避免內存泄漏。 引用通常不被認為是您需要再次刪除的內容,因此如果其他人看到該代碼(將新的對象分配給引用),它可能會混淆它們。
你可以做...
const Foobar &foobar = Foobar(someArg, anotherArg);
...如果你真的想要一個參考。 請注意,一旦foobar超出范圍,它引用的臨時對象將會死亡。 但是,當你可以直截了當地寫下時,寫作中沒有太多意義:
Foobar foobar(someArg, anotherArg);
您可能實際上並不需要引用...它們通常(但不是唯一地)用於方法參數的類型。 這樣您就可以傳遞看起來像對象的東西,但只有指針的大小,並且方法可以修改。 引用的引用主要是為了讓你編寫一個拷貝構造函數(我不會在這里解釋!)。
C ++中的引用實際上並不像人們期望的那樣強大,我認為混淆來自習慣於Java和C#之類的語言的人,這些語言沒有指針並且具有可以重新分配和使用的引用。
C ++中的引用通常最適合用作變量的別名,因此您可以簡化參數傳遞和返回值等操作。 在極少數情況下,您會嘗試以第一行的方式獲取引用。 所以通常你不需要做你想做的事:)
第二行當然是正確的,你可以從返回引用的函數中執行返回* foobar之類的操作。
你寫得對。 但請記住,通過刪除&refVar釋放ptr是很奇怪的; (它可能被誤認為是不是由new創建的變量)。
你應該看看GotW是否有好的做法繞過http://www.gotw.ca/gotw/我不記得那是什么課(當時還有一個以上)但是通過閱讀更有價值然后任何人意識到(陷阱將是少驚一覺)
你應該嘗試編寫永遠不會使用指針的代碼。 我這樣做但是當我需要一個BaseObj容器時卡住了。 沒有解決的問題。 通常我使用STL容器並在堆棧上擁有大多數變量{MyClass myVar; ...}或作為成員並根據需要傳遞它。
一旦你開始傳遞引用而不是指針並使用stl容器而不是new,它很容易刪除指針。 請注意,我從不使用auto_ptr。 矢量,字符串,雙端隊列,列表和地圖應該完成你需要的大部分工作。 還有其他容器。
不,你已經明白了。 一個foo&“指向”實際的對象,所以如果你真的想要一個foo引用,你必須取消引用foo指針。
雖然@Neil有一點意義 - 從語法上講,這就是你得到你想要的東西,但你為什么要這樣做呢?
我建議使用智能指針。 您需要管理所有權,並且引用不會為您執行此操作。 實際上,它會使調用者難以理解任何所有權問題。 正如Scott Langham在評論中提到的那樣,std :: auto_ptr會起作用。 使用Boost或TR1中的shared_ptr可能是個更好的主意。
boost::shared_ptr<Foobar> helloWorld()
{
boost::shared_ptr<Foobar> foobar(new Foobar(someArg, anotherArg));
foobar->HelloWorld();
return foobar;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.