類型擦除技術我想要掌握類型擦除技術,同時也分享那些,我知道。我希望找到一些有人在他/她最黑暗的時刻想到的瘋狂技巧。:)我所知道的第一個也是最明顯的,也是最常用的方法是虛函數。只需在基于接口的類層次結構中隱藏類的實現。許多Boost庫都這樣做,例如Boost.Any這樣做是為了隱藏你的類型,而Boost.Shared_ptr這樣做是為了隱藏(de)分配機制。然后有一個函數指針指向模板化函數的選項,同時將實際對象保存在void*指針中,如Boost.Function確實隱藏了仿函數的實際類型??梢栽趩栴}的最后找到示例實現。所以,對于我的實際問題:你知道其他什么類型的擦除技術?如果可能的話,請提供示例代碼,用例,您對它們的體驗以及可能的進一步閱讀鏈接。編輯(因為我不確定是否將此作為答案添加,或者只是編輯問題,我只會做更安全的問題。)另一個很好的技術來隱藏沒有虛函數或void*擺弄的東西的實際類型,是一個GMan在這里工作,與我的問題有關,這個問題究竟是如何運作的。示例代碼:#include <iostream>#include <string>// NOTE: The class name indicates the underlying type erasure technique// this behaves like the Boost.Any type w.r.t. implementation detailsclass Any_Virtual{
struct holder_base{
virtual ~holder_base(){}
virtual holder_base* clone() const = 0;
};
template<class T>
struct holder : holder_base{
holder()
: held_()
{}
holder(T const& t)
: held_(t)
{}
virtual ~holder(){
}
virtual holder_base* clone() const {
return new holder<T>(*this);
}
T held_;
};public:
Any_Virtual()
: storage_(0)
{}
Any_Virtual(Any_Virtual const& other)
: storage_(other.storage_->clone())
{}
template<class T>
Any_Virtual(T const& t)
: storage_(new holder<T>(t))
{}
~Any_Virtual(){
Clear();
}
Any_Virtual& operator=(Any_Virtual const& other){
Clear();
storage_ = other.storage_->clone();
return *this;
}
template<class T>
Any_Virtual& operator=(T const& t){
Clear();
storage_ = new holder<T>(t);
return *this;
}
void Clear(){
if(storage_)
delete storage_;
}
template<class T>
3 回答

皈依舞
TA貢獻1851條經驗 獲得超3個贊
C ++中的所有類型擦除技術都是使用函數指針(用于行為)和void*
(用于數據)完成的?!安煌狈椒ㄔ谔砑诱Z義糖的方式上略有不同。虛函數,例如,只是語義糖
struct Class { struct vtable { void (*dtor)(Class*); void (*func)(Class*,double); } * vtbl};
iow:函數指針。
也就是說,有一種我特別喜歡的技術:它shared_ptr<void>
只是因為它會讓那些不知道你可以做到這一點的人感到震驚:你可以將任何數據存儲在一個shared_ptr<void>
,并且仍然擁有正確的析構函數。結束,因為shared_ptr
構造函數是一個函數模板,默認情況下將使用為創建刪除函數而傳遞的實際對象的類型:
{ const shared_ptr<void> sp( new A );} // calls A::~A() here
當然,這只是通常的void*
/函數指針式擦除,但包裝非常方便。

神不在的星期二
TA貢獻1963條經驗 獲得超6個贊
從根本上說,這些是你的選擇:虛函數或函數指針。
如何存儲數據并將其與功能相關聯可能會有所不同。例如,您可以存儲指向基類的指針,并使派生類包含數據和虛函數實現,或者您可以將數據存儲在其他位置(例如,在單獨分配的緩沖區中),并且只需提供派生類虛函數實現,它void*
指向數據。如果將數據存儲在單獨的緩沖區中,則可以使用函數指針而不是虛函數。
如果您希望將多個操作應用于類型擦除數據,則即使數據是單獨存儲的,也可以在此上下文中存儲指針到基礎。否則,您最終會得到多個函數指針(每個函數指針對應一個類型擦除函數),或者帶有指定要執行的操作的參數的函數。
- 3 回答
- 0 關注
- 588 瀏覽
添加回答
舉報
0/150
提交
取消