1.7 Policy Classes的析構函數
我們已知host class從policy class公有繼承。那么將一個指向host class對象的policy class指針delete,將會產生不可預期的結果。解決方法有三:
1、將policy的析構函數聲明為虛函數。但這樣會妨礙policy的靜態連接特性,也會影響執行效率。第一個虛函數的加入會使對象大小帶來額外開銷。
2、采用protected繼承或private繼承(派生類指針將不能轉化為基類指針,cuigang)。但policy的函數則不能對外訪問,失去用戶擴充的特性(見1.6節)。
3、定義一個非虛的protected析構函數。(不能對基類指針delete,因為析構函數不可訪問,cuigang)
方法3顯然沒有1、2的副作用。
1.8 通過不完全具現化而獲得的選擇性機能
更進一步。由于對于模板類中的成員函數,如果未曾用到,那么它就不會被編譯器具現出來,有的編譯器甚至不對其進行語法檢查。如此便導致host class有機會指明并使用policy class的可選特性。如:
1 template < template <class> class CreationPolicy >
2 class WidgetManager : public CreationPolicy<Widget>
3 {
4 //
5 void SwitchPrototype(Widget* pNewPrototype)
6 {
7 CreationPolicy<Widget>& myPolicy = *this;
8 delete myPolicy.GetPrototype();
9 myPolicy.SetPrototype(pNewPrototype);
10 }
11 }
那么
1、如果你采用的CreationPolicy支持GetPrototype(),那么使用WidgetManager::SwitchPrototype()沒問題。
2、如果你采用的CreationPolicy不支持GetPrototype(),那么使用WidgetManager::SwitchPrototype()編譯出錯。
3、如果你采用的CreationPolicy不支持GetPrototype(),但是沒有使用WidgetManager::SwitchPrototype(),那么沒問題!!!
那么host class的作者就可以利用這種不完整具現化(incomplement instantiation),預定義一些可選的方法。