gpt4 book ai didi

c++ - 如何将 boost::object_pool 与 std::unique_ptr 一起使用?

转载 作者:搜寻专家 更新时间:2023-10-31 02:23:49 25 4
gpt4 key购买 nike

这是一个由以下代码说明的两部分问题:

#include <memory>
#include <vector>
#include <boost/pool/object_pool.hpp>

struct Foo {
Foo(int i) : _i(i) {}
void* operator new(size_t) = delete; // ***
int _i;
};

using FooHandle = std::unique_ptr<Foo>;

struct Bar {
Foo* addFoo(int i)
{
Foo* ptr = new (_fooPool.malloc()) Foo(i); // 111
return FooHandle(ptr,
&boost::object_pool<Foo,
boost::default_user_allocator_new_delete>::destroy); // 222
}
boost::object_pool<Foo> _fooPool;
};

我正在努力确保

  1. Foo 类型的对象仅由 Bar 类型的对象分配和拥有,
  2. 它们存储在池中,并且
  3. 它们通过唯一指针访问。

使用 Visual Studio 编译器我遇到了以下问题

  1. 如果我删除默认的 operator new(标有 *** 的行),则 placement new(标有 111 的行)不会编译。是我做错了什么还是 VS 的限制?

  2. 我想,为了在池中分配适当的 unique_ptr,我需要提供对池删除器的访问权限。标记为 222 的行是我尝试这样做的。编译器也不接受它。正确的语法是什么?

最佳答案

boost::object_pool::destroy是一个非static 成员函数,因此需要在object_pool 实例上调用它。此外,删除器是 unique_ptr 类型的一部分,因此必须相应地声明您的 FooHandle 别名。此外,您的 addFoo() 函数在应该返回 FooHandle 时返回了 Foo*

using FooHandle = std::unique_ptr<Foo, std::function<void(Foo *)>>;

FooHandle addFoo(int i)
{
Foo* ptr = new (_fooPool.malloc()) Foo(i);
return FooHandle(ptr, std::bind(&boost::object_pool<Foo>::destroy,
&_fooPool, std::placeholders::_1));
}

new 表达式的问题是您的 deleted new 重载隐藏了全局放置 new运算符(operator)。如果您还重载放置版本,代码将编译。

static void* operator new(size_t count, void *p)
{
return ::operator new(count, p);
}

Live demo

或者,显式调用全局operator new

Foo* ptr = ::new (_fooPool.malloc()) Foo(i);

您确定要处理已删除的 new 重载吗?这样做不会阻止某人使用 ::new Foo(10) 在您的对象池之外分配一个 Foo


作为 T.C.评论中提到,使用 std::function 来打包删除器远非理想。避免这种情况的一种方法是创建一个仿函数类型来存储对 object_pool 实例的引用,然后对该实例调用 destroy

struct FooDeleter
{
FooDeleter(boost::object_pool<Foo>& pool)
: pool(&pool)
{}

void operator()(Foo *p)
{
pool->destroy(p);
}
boost::object_pool<Foo> *pool;
};

using FooHandle = std::unique_ptr<Foo, FooDeleter>;

FooHandle addFoo(int i)
{
Foo* ptr = _fooPool.malloc();
if(ptr)
{
return FooHandle(::new (ptr) Foo(i), FooDeleter(_fooPool));
}
else
{
return FooHandle(nullptr, FooDeleter(_fooPool)); // or throw exception etc
}
}

Live demo

关于c++ - 如何将 boost::object_pool 与 std::unique_ptr 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28843379/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com