[英]unique_ptr deleter overhead
在普通的C ++設計,大多數對象可以通過一個被刪除delete
的說法, free
功能,或特定庫相當於free
。 對於此類對象, unique_ptr
Deleter
實現可以是通過Empty Base Class Optimization消除的無狀態對象。 但是,某些庫需要使用另一個對象(可能包含函數指針或其他某些上下文)來從該庫中刪除對象。
typedef struct lib_object lib_object;
struct lib_api {
lib_object (*createInstance)();
void (*freeInstance)(lib_object *o);
};
可以通過將lib_api
指針存儲為自定義Deleter
的數據成員來將其包裝在unique_ptr
,但是如果需要管理多個lib_object
實例(例如在容器中),則會使跟蹤對象的內存開銷加倍。 在處理此庫時,可以使用哪種模式來維護RAII原則,同時仍保持內存效率?
如果只有一個lib_api
對象,那么你可以讓你的刪除器獲得一個靜態指針。
如果可以有多個lib_api
對象,那么除了在Deleter中存儲指向它的指針之外別無選擇。
我為這些對象使用自定義刪除器模板。
template<typename T, T Function>
struct function_deleter
{
template<typename U>
auto operator()(U&& u) const noexcept(noexcept(Function(std::forward<U>(u))))
{
return Function(std::forward<U>(u));
}
};
然后你可以free
使用你的刪除電話:
unique_ptr<int, function_deleter<void(*)(void*), &free>> uniq;
它的大小仍然等於一個指針。 現場演示
來C ++ 17您將能夠將auto
用於非類型模板參數,將代碼簡化為:
template<auto Function>
struct function_deleter
{
template<typename U>
auto operator()(U&& u) const noexcept(noexcept(Function(std::forward<U>(u))))
{
return Function(std::forward<U>(u));
}
};
和
unique_ptr<int, function_deleter<&call_free>> uniq;
有了這個,在你的情況下,我將保留一個unique_ptr<pair<lib_object, lib_api>>
與靜態刪除器支持這種結構。
using lib_pair = pair<lib_object, lib_api>;
void lib_free(lib_pair* p){
p->second.freeInstance(p->first);
delete p;
}
using unique_lib_ptr = unique_ptr<lib_pair, function_deleter<void(*)(lib_pair*), &lib_free>>
這看起來更像緩存,但可能只是你的事情。
應該存在一個更優雅的解決方案,但我會寫一些類似的東西
template <class ContainerType>
class TObjectContainer : public ContainerType {
public:
TObjectContainer() = default;
TObjectContainer(const TObjectContainer&); // should call createCopy
TObjectContainer(TObjectContainer&&) = default;
~TObjectContainer()
{ for (lib_object* element : *this)
(*freeInstance)(element);
}
private:
void (*freeInstance)(lib_object *o);
};
typedef TObjectContainer<std::vector<lib_object*>> ObjectVector;
它不使用unique_ptr
但它基本上應該完成這項工作。
請注意,您可能會重載每個刪除方法,例如clear
,調用freeInstance
或pop_back
來返回原始的std::unique_ptr
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.