2

我处于将指针保存在向量中的情况,以便我可以使用它们来释放 dtor 中的内存。

我有一个对象监听来自 boost 信号的回调(槽)。这些对象的范围需要大于创建它的方法,因为它应该监听比创建位置晚得多的 boost 信号。所以,我必须在堆中分配内存并立即使用该实例订阅增强信号。

现在,当持有信号的类被销毁时,应该从内存中释放这些对象。现在我的选择是什么,

  • 当 boost 信号超出范围并且所有监听 boost:bind 对象被销毁时,boost 是否会释放所有这些对象?

  • 共享指针或智能指针会帮助我吗?

  • 我是否必须在信令服务中有一个包含所有这些指针的向量才能在其析构函数中释放?有更好的方法吗?

    void methodA(){
    
    CallbackHandler* cbHandler=new CallbackHandler(..);    //Allocating in heap as we want to receive boost signals on  
                                                           //this instance even after this method exits
    signalingService.subscribeToCertainSignals(signalType,boost::bind(&CallbackHandler::boostSlotListener,cbHandler,_1));
    }
    
    
    // Boost Signal -SignalingService
     boost::signal<void (const std::string &msg)> signal1;
     boost::signal<void (const std::string &msg)> signal2;
    
     void subscribeToCertainSignals(const std::string& signalType,boost::function<void (const std::string& str)> bindObject){
            this->signal1.connect(bindObject);
            this->signal2.connect(bindObject);
    
     }
     void sendSignals(A a){
         if(check){
            this->signal1("somestring1");
          }else{
            this->signal1("somestring1");
          }
    

    };

4

2 回答 2

1

您可以这样做的一种方法是将shared_ptrs 存储到持有信号的对象中的所有侦听器,并将weak_ptrs 存储到外部的侦听器。当持有信号的对象被销毁时,每个shared_ptrs 中的引用计数将转到0并且指向的侦听器将被删除。现在,当您下次尝试锁定weak_ptrs 以从持有信号的对象外部访问侦听器时,锁定将失败,因为指针将被删除 - 这很容易检测到,因为lock将返回 null shared_ptr

这是一个具体的例子(不幸的是,没有使用 Boost.Signals,只是为了说明这一点):

#include <iostream>
#include <memory>
#include <vector>

class Listener
{
public:
    virtual ~Listener() {}
    virtual void signal() = 0;
};

class Subject
{
private:
    std::vector<std::shared_ptr<Listener> > m_listeners;
public:
    void add_listener(const std::shared_ptr<Listener>& listener)
    {
        m_listeners.push_back(listener);
    }

    void signal_all()
    {
        // Note that you could use "auto it = ..." here in C++11.
        for(std::vector<std::shared_ptr<Listener> >::iterator it=m_listeners.begin(), iend=m_listeners.end(); it!=iend; ++it)
        {
            (*it)->signal();
        }
    }
};

class MyListener : public Listener
{
    void signal()
    {
        std::cout << "Signalled!\n";
    }
};

int main()
{
    std::vector<std::weak_ptr<Listener> > listeners;

    {
        Subject s;  

        std::shared_ptr<Listener> listener(new MyListener);
        s.add_listener(listener);
        listeners.push_back(listener);
        listener.reset();

        s.signal_all();

        // Locking the listener yields the listener here.
        std::cout << listeners[0].lock() << '\n';
    }

    // Locking the listener now yields null because s no longer exists.
    std::cout << listeners[0].lock() << '\n';

    return 0;
}

这输出:

Signalled!
<some valid non-null address>
00000000
于 2012-04-11T21:35:14.817 回答
0

我认为最好使用 boost scoped_connection。该对象专为您正在寻找的东西而设计。

例如,您可以将作用域连接存储在列表中,当列表的所有者死亡时,列表将调用作用域连接的析构函数,并且会自动断开您的对象与信号槽的连接。

在此处阅读详细信息:

http://www.boost.org/doc/libs/1_46_1/doc/html/boost/signals2/scoped_connection.html

于 2016-07-12T20:28:31.537 回答