簡體   English   中英

最佳做法與參考

[英]Best practices with references

僅出於好奇,教育和澄清的原因,我想問一下我使用參考和價值觀的方式是否是好的做法。

理論上:

class ComplexGraphicalShape {
...
public:
    void setRasterImageURL(const QString &rasterImageURL);
    const QString &rasterImageURL() const;
...
private:
    const QString *_rasterImageURL;
};

...

void ShadowGram::setRasterImageURL(const QString &rasterImageURL) {
    safeDelete(_rasterImageURL); // handle deletion
    _rasterImageURL = new QString(rasterImageURL);
}

const QString &ShadowGram::rasterImageURL() const{
    // Question 2: Why is it a problem if I return 
              // return "www.url.com/shape_url.jpg"
    return *_rasterImageURL; // that is the right way
}

...

complexGraphicalShape().setRasterImageURL(kURLImagesToShare + imageName);
complexGraphicalShape().setRasterImageURL("www.url.com/url.jpg"); // Question 1.

我的第一個問題是,我可以使用setRasterImageURL函數調用內部創建的臨時對象引用多長時間? 該變量在哪里?(如果沒有記錯,則在堆棧中,但是如果我使用該臨時引用調用另一個函數,該怎么辦?

我的第二個問題是,如果我想使用此return "www.url.com/shape_url.jpg" ,為什么在問題2部分得到警告? 那東西有點相似。 我可以使用該臨時對象多長時間?

感謝您的時間來回答和解釋

Q1:臨時字符串存在只要與它綁定的臨時引用。 那就是-只要您在setRasterImageURL()函數的“內部” setRasterImageURL() 當然-這包括所有稱為“此功能內”的功能。 請注意,存儲對該臨時字符串的另一個引用不會延長臨時對象的壽命。

complexGraphicalShape().setRasterImageURL("www.url.com/url.jpg");
// the temporary object is "destroyed" when it goes out of scope, and it's scope is just the called function

Q2:返回的問題是您使用“ C字符串”(字符數組)創建一個臨時QString對象(在堆棧上,仍在函數內部)並返回對該臨時對象的引用。 由於此函數返回后立即銷毀了該臨時對象,因此您的引用永遠無效,並且引用了死對象。 另一方面,返回對成員變量的引用是可行的,因為該對象未銷毀,因此只要您的主對象存在,該引用就有效。

const QString &ShadowGram::rasterImageURL() const{
    return "www.url.com/shape_url.jpg"
    // the temporary object is destroyed here, before the function returns, reference is invalid
}
  1. 臨時存在,直到setRasterImageURL返回,所以您可以安全地傳遞對其的引用,但是您需要注意不要保存該引用供以后使用。 臨時文件存儲在編譯器想要存儲的任何位置。 該引用很可能在寄存器或堆棧中傳遞。

  2. 這是一個問題,因為您要返回對臨時QString對象的引用,並且該對象在函數返回時被破壞。 您根本無法使用參考。

只要不存儲對函數的引用“向內”(通常)是安全的,而從函數中對引用進行“向外”傳遞則需要您確保函數返回時所引用的對象仍然存在。

我的第一個問題是,我可以使用setRasterImageURL函數調用內部創建的臨時對象引用多長時間?

它不是在函數調用內部創建的,而是在調用函數之前在調用者的堆棧上創建的,並在函數返回后銷毀。

該變量在哪里?(如果沒有記錯,則在堆棧中,但是如果我使用該臨時引用調用另一個函數,該怎么辦?

是的,在堆棧上。 它被摧毀; 函數調用返回后(在“完整表達式”的末尾)。

那東西有點相似。 我可以使用該臨時對象多長時間?

直到創建臨時語句的完整表達式(即return語句)的末尾為止, 因此在函數甚至還沒有完成 return它就超出了范圍 這就是為什么您會收到警告的原因-返回的引用已綁定到一個不再存在的對象,並且永遠無法安全使用。

標准中的12.2 [class.temporary]第5段涵蓋了這兩種情況:

—綁定到函數調用(5.2.2)中的參考參數的臨時對象一直存在,直到包含該調用的完整表達式完成。
—函數返回語句(6.6.3)中臨時綁定到返回值的生存期; 臨時在return語句中的全表達式結束時銷毀。

暫無
暫無

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

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