Is there a way to increase the efficiency of shared_ptr by storing the reference count inside the controlled object?

谁说胖子不能爱 提交于 2019-12-01 20:39:28

A partial solution is to use make_shared to create your shared_ptrs. For example,

auto my_thing = std::make_shared<Thing>();

instead of

auto my_thing = std::shared_ptr<Thing>(new Thing);

It's still non-intrusive, so nothing else needs to change. Good implementations of make_shared combine the memory allocation for the reference count and the object itself. That saves a memory allocation and keeps the count close to the object for better locality. It's not quite as efficient as something like boost:intrusive_ptr, but it's worth considering.

Use a boost::intrusive_ptr which is designed to work on a class with an embedded reference count.

Non-tested example based on example here:

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(); 
    }; 
}; 
sellibitze

If you want to reduce the overhead of distinct memory allocations for your object and the reference counter, you could try to use make_shared. That's what its for.

pm100

you can save some overhead by simply getting rid of the two classes and having just one and typedefing a shared ptr to it - this is the idom i use all the time

 class Resource
 {
      ...
 };
 typedef boost::shared_ptr<Resource> ResourcePtr;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!