如何将std :: shared_ptr添加到多个STL容器中?

时间:2013-11-28 12:28:26

标签: c++ c++11 stl smart-pointers

将共享指针传递给不同对象中的stl容器的正确方法是什么,所以没有对象的早期破坏?

我有多个带有std :: queue的系统:

class System {
    typedef std::shared_ptr<Event> EventPtr;
protected:
    std::queue<EventPtr> mEventQueue;

    static SystemManager * sSystemManager;
   //this holds all the systems in the application

public:
    System();
    ~System();

    void addEventToQueue(EventPtr event) {
        mEventQueue.push(event);
    }

    void callEventQueue() {
        while(!mEventQueue.empty()) {
           acceptEvent(mEventQueue.front().get());
           mEventQueue.pop();
         }
    }

    void acceptEvent(Event * event);

public:
    static void sendEvent(EventPtr &event) {
        for(auto system : sSystemManager->getSystems()) {
               system->addEventToQueue(event);
        }
    }
};

我想知道我是否理解得恰到好处:

当我在作用域中调用System::sendEvent(std::make_shared<Event>("testEvent"));时,它将共享指针作为引用传递,该引用不会创建新指针,也不会增加引用计数。但是,addEventToQueue函数将参数作为对象传递,因此引用计数增加;如果我有5个系统,引用计数将为6(计算std :: make_shared本身)。但是这个引用计数存储在哪里?它是通过std::make_shared创建的第一个共享指针吗?或者所有对象中的计数相同?那么,当第一个对象超出范围时,其他对象会发生什么?他们如何知道正确的引用计数是什么,因为他们只知道“父”对象?

我读到的关于共享指针的所有文章,引用计数的方式总是很常见。计数器是静态变量吗?

1 个答案:

答案 0 :(得分:4)

其中完全存储的计数取决于实现。但是,该标准规定它必须具有这样的行为,以便共享std::shared_ptr<T>的一个实例的所有权的T的所有实例使用相同的引用计数。实际上,这意味着引用计数是动态分配的,并且指向它的指针由std::shared_ptr<T>的所有相关实例共享。

这就是std::make_shared()是创建共享指针的首选方式的原因之一 - 它可以为引用计数(以及所需的其他维护结构)和一个分配请求中的对象分配内存,而不是两个分开的。这样可以提高分配的性能,也可能提高指针的使用性能(因为引用计数和对象在内存中的距离更近,从而降低了缓存未命中率)。