这正在成为我的代码中的常见模式,因为当我需要管理一个不可复制的对象时,因为 A. 它是“重”或 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();
};
};
这样,shared_ptr 就可以解决引用计数的问题,允许Resource
是可复制的,即使底层句柄只有在所有对它的引用都被销毁后才应关闭。
然而,如果我们可以将数据移动到内部,我们似乎可以节省分配shared_ptr的引用计数的开销以及单独的开销Implementation
不知何故,就像 boost 的侵入式容器一样。
如果这让一些人对过早的优化感到烦恼,那么我实际上同意我当前的项目不需要它。但我很好奇这是否可能。
部分解决方案是使用make_shared
来创造你的shared_ptr
s。例如,
auto my_thing = std::make_shared<Thing>();
代替
auto my_thing = std::shared_ptr<Thing>(new Thing);
它仍然是非侵入性的,因此不需要改变其他任何东西。良好的实施make_shared
结合引用计数和对象本身的内存分配。这节省了内存分配并使计数接近对象以获得更好的局部性。它不像类似的东西那么有效boost:intrusive_ptr
,但值得考虑。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)