簡體   English   中英

將auto_ptr與C ++中的引用結合

[英]Combining auto_ptr with references in C++

前一段時間,我決定嚴格遵循該規則來檢查每個指針,然后在范圍內首次對其進行引用之前,還適當地更改了指向引用的指針:在某些情況下在代碼庫中是靜態的,在某些情況下是動態的(在聲明了指針當然不是null)。 最終導致這樣的代碼:

std::string LoadText0(const std::string& fileName)
{
    TStrings& lines = *new TStringList;
    lines.LoadFromFile(fileName.c_str());
    std::string result = lines.Text.c_str();
    delete &lines;
    return result;
}

...我不太喜歡,但是與上述規則一致,因為我根本不關心失敗的消息:我保證它會根據編譯器設置拋出異常。

但是:此代碼遠非異常安全的。 由於靜態分析工具Cppcheck在當前版本1.65中存在問題,說明我嘗試刪除會導致未定義行為的自動變量,因此我發現缺少值得重寫代碼的異常安全性,現在我使用的是std::auto_ptr

但是現在,我不喜歡所有的->運算符:它們給人一種錯誤的感覺,即可以選擇分配指針。 當范圍變大時,此外觀尤其成問題,並且將所有點重寫為箭頭也需要大量工作。

std::string LoadText1(const std::string& fileName)
{
    std::auto_ptr<TStrings> lines(new TStringList);
    lines->LoadFromFile(fileName.c_str());
    std::string result = lines->Text.c_str();
    return result;
}

因此,我試圖找出一種結合了兩個方面的優點的解決方案,這就是我所發現的(帶有指向同一對象的兩個“訪問點”的缺點)

std::string LoadText2(const std::string& fileName)
{
    std::auto_ptr<TStrings> plines(new TStringList);
    TStrings& lines = *plines;
    lines.LoadFromFile(fileName.c_str());
    std::string result = lines.Text.c_str();
    return result;
}

這是您眼中的濫殺濫傷嗎? 您認為它是慣用的嗎?

好吧,這可能只是觀點,但我將嘗試證明觀點的合理性。

我認為在第二個示例中使用->更慣用。 熟練的c ++讀者可以立即清楚自己在做什么。

通過將指針變成摘要3中的引用,您正在插入(恕我直言)一條無用的代碼行,其唯一好處是可以緩解因使用->運算符而煩惱的任何人。

如果未分配指針,則在嘗試將其轉換為引用時,將遇到與使用該指針時相同的錯誤。 因此它什么也沒做。 因此,我認為代碼既不會完成任何事情,也不會澄清代碼-這是噪音,不是信號,在代碼審查中,我建議將其刪除。

考慮到您必須在堆上分配並且只有auto_ptr可用的限制,我發現您的第二個解決方案是正確的。 為了向代碼的讀者保證假定已分配了指針,我建議遵循“ C ++編碼標准”(Sutter和Alexandrescu->和優秀閱讀)中的准則68,該准則指出“自由聲明以記錄內部假設和不變。“

因此,在初始化(自動)指針之后,立即添加以下行:

斷言(線);

對於任何閱讀您的代碼的人來說,它可以作為文檔,您可以肯定地確定沒有未初始化的指針將到達代碼的那一點,並且它充當對您的假設有效的調試(而非發布)時間測試。 雙贏。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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