如果您將舊的C風格的類型轉換爲類型A到類型B,而類型A不能轉換爲類型B,那麼C++標準是否定義了特定的行爲?反之亦然?是否定義了運行時錯誤的C風格轉換的行爲?
會有一個已知的可見行爲,可以被認爲是在運行時使用此非法轉換的症狀嗎?
如果您將舊的C風格的類型轉換爲類型A到類型B,而類型A不能轉換爲類型B,那麼C++標準是否定義了特定的行爲?反之亦然?是否定義了運行時錯誤的C風格轉換的行爲?
會有一個已知的可見行爲,可以被認爲是在運行時使用此非法轉換的症狀嗎?
四種C++風格演員中只有一種決定了演員在演出時的合法性,即dynamic_cast
。
C風格演員陣容對應於其他三個陣容的組合(static_cast
,reinterpret_cast
,const_cast
)。這些演員的有效性是在編譯時確定的,或者如果在編譯時無法確定,那麼演員被認爲是有效的。 C風格演員絕不會像dynamic_cast
那樣行事。
因此,在運行時「失敗」的C風格轉換,即打破了有效性假設,導致未定義的行爲。所以:
如果您將舊的C風格的類型轉換爲類型A到類型B,其中類型A不能轉換爲類型B,反之亦然,C++標準是否定義了特定的行爲?
號
會不會有,可以認爲是使用這種在運行時非法投症狀已知可見的行爲?
號
感謝這就是我想知道的全部 – Allahjane
[另請參見此處](http://stackoverflow.com/questions/17925124/can-i-cast-a-derived-class-to-a-private-base-class-using -c-style-cast),這個C風格轉換不等同於C++風格轉換的任何組合 –
編譯器會趕上他們中的一些,但不是全部。這是一個災難性的鑄件的例子:
#include <iostream>
#include <string>
using namespace std;
class A {
public:
A(std::string s, int x) : m_s(s), m_x(x) {}
void print() { cout << "A::print(): str = " << m_s << ", x = " << m_x << endl; }
private:
std::string m_s;
int m_x;
};
class B {
public:
B(int x) : m_x(x) {}
void print() { m_x++; cout << "B::print(): x = " << m_x << endl; }
private:
int m_x;
};
int main(int argc, char **argv) {
A *a = new A("abc", 1);
a->print();
B *b = (B*)a;
b->print();
a->print();
return 0;
}
海合會結果(Ubuntu的5.4.0-6ubuntu1〜16.04.4)5.4.0 20160609:
A::print(): str = abc, x = 1
B::print(): x = 24828977
A::print(): str = bc, x = 1
是的,我們叫B的方法上A的數據,這意味着我們的C風格演員工作爲reinterpret_cast
。 reinterpret_cast
只需要一個內存區域,並允許你對待是不同的東西。這裏沒有安全帶。
在另一方面,如果你嘗試編譯這樣的事情
A a;
B b;
a = (A)b;
return 0;
會造成static_cast
和編譯時錯誤。所以C風格的轉換結果取決於上下文。
這是NIGHTMARE當處理模板和auto
。
爲了避免此問題,使用static_cast
(用於編譯時檢查)和dynamic_cast
(運行時檢查)或reinterpret_cast
(用於指針和POD),寫明你的意圖。
實際上你的結果可能只發生在你的機器/編譯器上 - 我得到一個[運行時錯誤](http:// ideone的.com/CsdaXh)。 b:print();'調用*未定義的行爲* – UnholySheep
B :: print()修改由'std :: string'佔據的sizeof(int)'字節。你可能會在那裏觀察到內存腐敗 – ezaquarii
[reinterpret_cast']的文檔(http://en.cppreference.com/w/cpp/language/reinterpret_cast)在此清楚 - 你正在調用UB。也不知道內存損壞是如何影響的,因爲您的結果不能保證,並且不同的編譯器會引發運行時錯誤。 – UnholySheep
我認爲你應該提供一個例子。例如:你在談論POD類型,類別,原始類型,指針,...? – UnholySheep
好吧,全部都是 – Allahjane
取決於實際的代碼,C風格的轉換可以等同於3種不同C++類型轉換('static_cast','reinterpret_cast'或'const_cast')中的任何一種。這些'static_cast'會拋出編譯時錯誤,而'reinterpret_cast'會(在大多數情況下)導致UB(如果拋出是非法的) – UnholySheep