Bil*_*eal 3 c++ boost shared-ptr
这在我的代码中已经成为一种常见模式,因为当我需要管理一个需要不可复制的对象时,因为它是"重"或B.它是操作系统资源,例如关键部分:
class Resource;
class Implementation : public boost::noncopyable
{
friend class Resource;
HANDLE someData;
Implementation(HANDLE input) : someData(input) {};
void SomeMethodThatActsOnHandle() {
//Do stuff
};
public:
~Implementation() { FreeHandle(someData) };
};
class Resource
{
boost::shared_ptr<Implementation> impl;
public:
Resource(int argA) explicit {
HANDLE handle =
SomeLegacyCApiThatMakesSomething(argA);
if (handle == INVALID_HANDLE_VALUE)
throw SomeTypeOfException();
impl.reset(new Implementation(handle));
};
void SomeMethodThatActsOnTheResource() {
impl->SomeMethodThatActsOnTheHandle();
};
};
Run Code Online (Sandbox Code Playgroud)
这样,shared_ptr处理引用计数问题,允许Resource可复制,即使基础句柄只有在对它的所有引用都被销毁后才应该关闭.
但是,似乎我们可以节省分配shared_ptr的引用计数的开销,如果我们可以在Implementation某种程度上移动内部数据,就像boost的侵入式容器那样.
如果这使得过早的优化讨厌唠叨某些人,我实际上同意我不需要这个用于我当前的项目.但我很好奇是否有可能.
使用boost :: intrusive_ptr,它设计用于具有嵌入引用计数的类.
基于此示例的未经测试的示例:
class Resource;
class Implementation : public boost::noncopyable
{
friend class Resource;
HANDLE someData;
int refCount; // The reference count.
Implementation(HANDLE input) : someData(input) { refCount = 0; };
void SomeMethodThatActsOnHandle() {
//Do stuff
};
public:
~Implementation() { FreeHandle(someData) };
};
intrusive_ptr_add_ref(Implementation* imp) { imp->refCount++; }
intrusive_ptr_release(Implementation* imp) { if(--imp->refCount) == 0) delete imp; }
class Resource
{
boost::intrusive_ptr<Implementation> impl;
public:
Resource(int argA) explicit {
HANDLE handle =
SomeLegacyCApiThatMakesSomething(argA);
if (handle == INVALID_HANDLE_VALUE)
throw SomeTypeOfException();
impl.reset(new Implementation(handle));
};
void SomeMethodThatActsOnTheResource() {
impl->SomeMethodThatActsOnTheHandle();
};
};
Run Code Online (Sandbox Code Playgroud)
部分解决方案是make_shared用来创建你shared_ptr的.例如,
auto my_thing = std::make_shared<Thing>();
Run Code Online (Sandbox Code Playgroud)
代替
auto my_thing = std::shared_ptr<Thing>(new Thing);
Run Code Online (Sandbox Code Playgroud)
它仍然是非侵入性的,所以没有其他东西需要改变.良好的实现make_shared结合了引用计数的内存分配和对象本身.这样可以节省内存分配并使计数靠近对象以获得更好的局部性.它不像那样有效boost:intrusive_ptr,但值得考虑.
| 归档时间: |
|
| 查看次数: |
899 次 |
| 最近记录: |