臨時死引用的與-O3
與-O2
編譯也許當以下最低十歲上下的程序段錯誤,但-O0
執行罰款(與鏗鏘4.0):檢測或避免在編譯時
#include <iostream>
class A {
public:
virtual void me() const { std::cerr << "hi!\n"; }
};
class B {
public:
B(const A& a_) : a(a_) {}
virtual void me() const { a.me(); }
private:
const A& a;
};
class C {
public:
C(const B& b_) : b(b_) {}
void me() const { b.me(); }
public:
const B& b;
};
int main() {
C c = C(A());
c.me();
}
的原因是該c.b
被初始化到從一個臨時A
構造B
類的臨時對象的引用。構造c.C()
退出後,臨時B
走了,但對它的引用仍然c.b
。
我可以採用什麼好的做法,以避免出現這種情況,因爲我無法控制的B
或A
執行?是否有靜態分析儀能夠檢測到這種情況? (我的scan-build
版本沒有發現問題。)
相關:Detect dangling references to temporary
好,U現在,右值引用。它們只綁定到臨時對象。我想也許這可以作爲一個只有左值的ref-wrapper抽象出來。 –
通常,不要聲明類型引用的成員變量。改用指針。如果你在構造函數中得到一個指針,結果代碼將會很明顯。 – rodrigo
@rodrigo:這聽起來很有趣。我想這也可以工作,如果我只聲明構造函數參數作爲指針,然後初始化引用?我寧願不重寫所有使用引用的代碼... – krlmlr