Nik*_*ita 6 c++ visual-c++ c++14 c++17
目前我正在研究自定义内存分配,其中一个缺点是我必须编写多行来实现new-expression只需一个简单调用所提供的相同结果.
简单初始化:
MyClass *obj = new MyClass(3.14);
Run Code Online (Sandbox Code Playgroud)
初始化不太简单:
void *obj_mem = alloc->Allocate(sizeof MyClass, alignof(MyClass));
MyClass *obj = new(obj_mem) MyClass(3.14);
Run Code Online (Sandbox Code Playgroud)
我将为我的项目组提供像那样的分配器,并希望它们实际使用它们,而不是回到调用new,因为我们需要这些更快的分配器来管理我们的内存.
但为了实现这一点,我将不得不设计最简单的语法来使用我的自定义分配器初始化变量.
我最好的选择是覆盖operator new每个类,因为它是new-expression 的分配函数.
class MyClass
{
...
void* operator new(size_t size, Allocator *alloc)
{
return alloc->Allocate(size, alignof(MyClass));
}
}
Run Code Online (Sandbox Code Playgroud)
然后初始化变量的语法成为我最终想要的:
MyClass *obj = new(alloc) MyClass(3.14);
Run Code Online (Sandbox Code Playgroud)
但是,如果我能得到与上述相同的一般信息,那就太好了.所以我不必operator new为每个班级重写.
彻底杀掉new。无论如何,你必须将创造与破坏捆绑在一起。
template<class T>
struct destroy {
Alloc* pool = nullptr;
void operator()(T* t)const {
ASSERT(t);
t->~T();
ASSERT(alloc);
alloc->Dealloc( t );
}
};
template<class T>
using my_unique_ptr = std::unique_ptr<T, destroy<T>>;
namespace details{
template<class T, class...Args>
my_unique_ptr<T> my_make_unique( Alloc* alloc, Args&&...args ) {
void* p_data = alloc->Allocate(sizeof(T), alignof(T));
try {
T* ret = ::new(p_data) T(std::forward<Args>(args)...);
return {ret, destroy<T>{alloc}};
} catch (...) {
alloc->Dealloc( p_data );
throw;
}
}
}
/// usual one:
template<class T, class...Args>
my_unique_ptr<T> my_make_unique( Alloc* alloc, Args&&...args ) {
return details::my_make_unique<T>( alloc, std::forward<Args>(args)... );
}
// permit leading il:
template<class T, class U, class...Args>
my_unique_ptr<T> my_make_unique( Alloc* alloc, std::initializer_list<U> il, Args&&...args ) {
return details::my_make_unique<T>( alloc, il, std::forward<Args>(args)... );
}
// for {} based construction:
template<class T>struct tag_t{using type=T;};
template<class T>using no_deduction=typename tag_t<T>::type;
template<class T>
my_unique_ptr<T> my_make_unique( Alloc* alloc, no_deduction<T>&&t ) {
return details::my_make_unique<T>( alloc, std::move(t) );
}
Run Code Online (Sandbox Code Playgroud)
现在my_make_unique需要一个Alloc*和 构造参数,它返回一个绑定了销毁代码的智能指针。
这个唯一的指针可以隐式地传递给 a std::shared_ptr<T>(通过 move)。
| 归档时间: |
|
| 查看次数: |
341 次 |
| 最近记录: |