2013-01-23 34 views
-1

我有一個類包含聯合作爲一個字段。該聯盟是指向兩個不同類別的指針。作爲第二個字段,我的類包含一個標誌,通知哪種類型當前存儲。C++異常和錯誤的聯合閱讀

class Item { 
    std::string *title; 
    bool who_am_I; 
    union { Submenu *smenu; Function *call; } content; 
    public: 
    bool am_I_a_submenu(); 
    bool am_I_a_function(); 
    Submenu *give_me_submenu(); 
    Function *give_me_function(); 
    /*(...)*/ 
}; 

現在,我的「give_me」方法的每一個在使用前我敦促用戶檢查通過適當的方法訪問標誌的類型,即「am_I」方法。不過,如果用戶偶然忘記它,我希望我的圖書館能夠拋出適當的異常。我可以這樣做,而不檢查「give_me」方法內的標誌嗎?我問,因爲這意味着在正常使用情況下,標誌被不必要地檢查兩次。

我想知道,如果一旦類型的衝突會導致程序運行出現故障,C++會在什麼時候拋出一些異常。或者,也許我應該處理這種情況,否則,最好沒有雙重檢查國旗。

+1

不要擔心'檢查兩次':沒關係(只要檢查函數是內聯的),因爲'who_am_I'和union會在同一個緩存行中。 – Sjoerd

+0

您是否嘗試使用多態而不是使用聯合來創建Item的兩個子類? 通過這種方式,你可以避免使用bool,通過使用多態來檢查你的物品的類型。 – tsukasan

+1

它是否被內聯並不重要。支票的成本可以忽略不計。 –

回答

4

好的,首先...爲什麼你關心國旗是否被檢查過兩次?那確實是是您的產品中嚴重的性能瓶頸,分析顯示必須進行優化?我非常懷疑它非常

但即使是性能瓶頸,更重要的是什麼? A 正常運行不會崩潰的應用程序在我看來似乎是超小額外開銷的可接受折衷。

但是,你應該重新設計你的界面,以便用戶總是知道他有什麼,不能犯這樣的錯誤。

0

通過使用聯合,您告訴編譯器這兩種類型是兼容的。通常從兩者轉換會導致編譯時問題,因爲沒有用戶指定的,也沒有默認轉換,但是因爲您將它定義爲聯合,所以這兩種類型都有默認轉換。

我會假設一個額外的調用來檢查一個布爾值在這種情況下可能不太昂貴。

1

無法檢查聯合內部存儲的內容。如果您使用聯合,那麼確保您始終訪問正確的元素取決於您。讀錯的是未定義的行爲,不會拋出異常。

我不知道你在做什麼,但我建議你不要使用union。這是一種古老的方式來節省一些記憶,不值得它可能引入的錯誤。在你的情況下,它根本不節省內存(由於內存對齊,前面的布爾值佔用指針的內存)。