從構造函數內調用虛擬成員函數
從構造符內調用虛擬函數是前期聯編的,這樣,它就短路掉了那些原本可能的簡潔的能力:
class Base
{
public:
Base();
virtual void BuildSection();
};
class Subclass:public Base
{
public:
Subclass();
virtual void BuildSection();
};
Base::Base()
{
BuildSection();
};
在此例中,程序員希望構造函數能夠多態地調用BuildSection(),當正在構造的對象是Base對象時調用Base::BuildSection(),當對象是類Subclass對象時調用Subclass::BuildSection()。
由于下列簡單的原因這個例子不起作用:當調用BuildSection()完成時,正在構造的對象僅僅是一個Base對象。即使對象最終成為Subclass對象,也要等到Subclass的構造函數把它過一遍以后。在這些情況下調用Subclass::BuildSection()可能是致命的。即使對象將最終成為Subclass對象,但在調用BuildSection()的時候,對象只不過是Base對象,而且,這個調用必須要前期聯編到函數Base::BuildSection()。
指針對準
當你在80x86處理器(例如,你的PC機的芯片)上執行你的程序時,這個問題不是致命的,但對其他的絕大多數芯片來說,這就是致命的了。它還會對你的應用程序移植到某個其他環境的能力產生影響。此外,甚至對于Intel 處理器來說,這個問題也將導致低于標準的性能。
當你的指針從一種類型轉換到另一種類型的時候,就有可能產生一個非對準指針(misaligned pointer)。處理器一般要求內存塊的地址要與一個和這個內存塊的尺寸匹配的邊界對齊。例如,字只能在字邊界上被訪問(地址是二的倍數),雙字只能在雙字邊界上被訪問(地址是四的倍數),依次類推。
編譯器通常確保監視這個規則。但是當你的指針類型從一種類型轉換成較大類型時,你就可以很輕易地違反這個規則:
char cA;
char* pC = &cA;
int* pI;
pI = (int*)pC;
*pI = 0; // this may be fatal.
因為字符僅僅是一個字節長,所以地址&cA可能有任意值,包括奇數值。可是,pI應只包含四的倍數的地址。通過轉換,答應把pC賦給pI,但是假如地址不是四的倍數,則接著發生的賦值可能使程序崩潰。
對于Intel處理器來說,甚至當pC值為奇數時,該賦值也不是致命的;雖然占用的時間要長得多,但是賦值還是能夠正常執行。請你謹防非對準指針。
這種情況只在你正在把你的指針從指向一種類型轉換成指向較大類型時才會出現。
相關推薦:北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內蒙古 |