2013-05-15 66 views
2

考慮以下定義:這是保證演員安全嗎?

struct A { 
    // ... 
}; 

struct B : public A {}; // empty 

void f(B& b) { /* use b */} 

void g(A& a) { 
    f(static_cast<B&>(a)); // is this a safe downcast? 
} 

int main() { 
    A a; 
    g(a); 
} 

在上面的例子a真是A一個實例。

既然B有一個空的定義,我想知道是否在這個特定的情況下調用f及其執行是未定義的行爲。

+0

它不是一個真正的「沮喪」,更像是一個「倒戈」! – typ1232

+0

@ typ1232:從超類型(又名基類)轉換爲子類型(又名派生類)通常稱爲「向下轉換」,即使「基」聽起來像它應該在底部。 –

回答

6

不,這不是合法的強制轉換,因爲它在非B類型的對象上執行。你的程序有未定義的行爲。

每一段的C++ 11標準的5.2.9/2:

類型「CV1B」,其中B是一個類類型的左值,可以轉換爲輸入「參考到CV2 D「,其中D是從B類 衍生(第10)中,如果從一個有效的標準轉換‘指針D’到‘指針B’的存在(4.10), CV2是相同的CV-資質認證或者更大的cv資格,cv1B既不是虛擬基類 的D也不是虛擬基類的基類D。結果類型「CV2D」類型的x值「CV1B」 可以鑄造到輸入「右值參照CV2D」與相同的約束作爲類型的左值「CV1B如果」cv1 B「類型的對象實際上是D類型對象的子對象,則結果指的是封閉的 對象D類型。否則,行爲是不管你的意思是安全什麼不確定

+0

帶有OP的'A'和'B'的'B'和'D'角色,D的派生自B,從'D *'到'B *'有一個有效的標準轉換,cv的匹配,沒有虛擬基地。 – jthill

+0

@jthill:是的。而類型爲A的對象'a'(在標準的文本中對應的是'B')實際上不是類型'B'的對象的子對象(對應於'D')所以行爲是不明確的 –

+0

讓我失明。 – jthill

2

號,即投是不正確的,真正的目標是A型的,而不是B所以你不能垂頭喪氣到B