簡體   English   中英

我是否正確初始化了我的C ++引用變量?

[英]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引用無效初始化

更新1:

請記住我正在返回此值,因此我不想使用局部變量; 我想在堆上使用一個值,而不是堆棧:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM