我有一個實現引用計數的C++類,我希望此類的所有用戶只能從這個類繼承,因此沒有任何對象會以多個引用計數器結束。如何檢測和斷言特定類的虛擬繼承?
我想在編譯時或至少在運行期間以某種方式來斷言這個需求。
有沒有辦法做到這一點?
我有一個實現引用計數的C++類,我希望此類的所有用戶只能從這個類繼承,因此沒有任何對象會以多個引用計數器結束。如何檢測和斷言特定類的虛擬繼承?
我想在編譯時或至少在運行期間以某種方式來斷言這個需求。
有沒有辦法做到這一點?
我認爲包裝課是最簡單的選擇。而不是直接從RefCounter繼承創建一箇中介類。
struct RefCounterVirtPrivate_
{
int count;
RefCounterVirt()
: count(0)
{ }
};
struct RefCounter : public virtual RefCounterVirtPrivate_
{
};
struct A : public RefCounter { };
struct B : public RefCounter { };
struct C : public A, public B { };
然後,一切都可以從RefCounter
繼承而不需要關心虛擬的傳承。你甚至不需要改變任何現有的代碼 - 虛擬繼承RefCounter
本身應該是無害的。
這當然不能保證人們不會直接從RefCounterVirtPrivate_
繼承,但這就是爲什麼我給它一個明顯的名字。意外地做到這一點比忘記virtual
關鍵字更難。
它應該是可能的一些欺騙,但考慮其含義:你設置的政策,對象需要立即自毀,如果其參考計數器達到零。
根據您的應用程序,你可能要離開的確切時間時,它調用delete this;
對象的實現,即只有在基類add_ref()
和release()
抽象函數(這使得一個具體實施中出現所有的接口vtables都有適當的thunking)並且將維護引用計數的負擔放在具體的類上。
像這樣的東西?
struct RefCounter {
template <typename T>
RefCounter(T *) {
BOOST_STATIC_ASSERT(boost::is_virtual_base_of<RefCounter, T>);
}
};
struct GoodClass : virtual RefCounter {
GoodClass() : RefCounter(this) {}
};
struct BadClass : RefCounter {
BadClass() : RefCounter(this) {}
};
這是一個關於需要通過this
的構造,雖然捕捉到派生類型的恥辱。當然,一個狡猾的用戶可以通過傳遞this
以外的東西來顛覆它。
您可以使用CRTP而不是'this',但我認爲您的解決方案更好。 – sbi 2011-12-19 10:05:49
@sbi:我認爲,但是'RefCounter
如果一個類繼承兩個基地,一個基地從'RefCounter'虛擬繼承,另一個基地繼承非虛擬? – sharptooth 2011-12-19 10:09:08
實際上,這個類在任何時候都會自己刪除'',所以我可以在'addref()'/'release()'中進行檢查。所以詭計是受歡迎的。 – sharptooth 2011-12-19 10:04:36