我正在尝试编写类似类的升压信号(作为学习 C++ 的练习)。我发现当我使用 enable_shared_from_this
时,我总是在析构函数中崩溃。这是代码(我使用的是 vs2012 update 2):
对此有何评论?这个问题应该是由 shared_from_this()
引起的,因为当我取消注释 signal_connection::disconnect
中的 (auto this_ = shared_from_this();
) 行时,一切正常。
我知道在调用 shared_from_this()
之前它必须至少有一个有效的 shared_ptr。我的代码应该满足这一点。
代码:
#include <memory>
#include <map>
class slot_manager;
class signal_connection: public std::enable_shared_from_this<signal_connection>
{
public:
signal_connection(slot_manager* manager)
:manager_(manager)
{}
public:
void disconnect() ;
private:
slot_manager* manager_;
};
class slot_manager
{
public:
typedef std::shared_ptr<signal_connection> connection_type;
typedef std::map<connection_type, int> map_type;
typedef map_type::value_type map_value_type;
public:
void connect(int slot)
{
std::shared_ptr<signal_connection> c(new signal_connection(this));
slots_.insert(map_value_type(c, slot));
}
~slot_manager()
{
auto iter = slots_.begin();
map_type::iterator iter2 = slots_.end();
while (iter != slots_.end())
{
iter2 = iter++;
iter2->first->disconnect();
}
}
void disconnect(std::shared_ptr<signal_connection> connection)
{
auto c = slots_.find(connection);
if (c != slots_.end())
{
slots_.erase(c);
}
}
protected:
map_type slots_;
};
void signal_connection::disconnect()
{
if (manager_ != nullptr)
{
//auto this_ = shared_from_this();
manager_->disconnect(shared_from_this());
manager_ = nullptr;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
slot_manager x;
x.connect(1);
return 0;
}
最佳答案
问题是,在您将其管理器设置为 nullptr
之前,signal_connection 在 disconnect()
中被销毁,然后导致访问冲突,即通过调用经理的断开连接。这是因为管理器持有连接的唯一 shared_ptr
,而您 erase()
那个。该对象不会使自己保持事件状态。当然,除非您取消注释该行。 this_
只存在足够长的时间来规避问题。
关于c++ - 使用 std::enable_shared_from_this 时析构函数崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17343686/