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();
    };
};
这样,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(); 
    }; 
}; 
部分解决方案是make_shared用来创建你shared_ptr的.例如,
auto my_thing = std::make_shared<Thing>();
代替
auto my_thing = std::shared_ptr<Thing>(new Thing);
它仍然是非侵入性的,所以没有其他东西需要改变.良好的实现make_shared结合了引用计数的内存分配和对象本身.这样可以节省内存分配并使计数靠近对象以获得更好的局部性.它不像那样有效boost:intrusive_ptr,但值得考虑.