简体   繁体   中英

shared_from_this throws an exception

I am writing Qt-based app with Blender-like functionality.

It consists of a 'framework' which is GUI + plugin system and plugins. Plugins are Qt dlls with objects (eg a Sphere, a Box, etc.) that can be basically created and displayed. All those objects, once created, are stored in the framework in some kind of a container structure which holds shared_ptr's to them (so actually the container is pretty much like vector<shared_ptr<INode>> )

What I want is to use shared_from_this() function inside one of plugins. Eg Here's a sample plugin (code changed for clarity):

class Q_DECL_IMPORT SphereNode: public INode, public Sphere

Where INode is:

class INode: public QObject, public boost::enable_shared_from_this<INode>

,a base class for everything stored in the container. So the problem is that this function:

void SphereNode::update()
{
 foo(shared_from_this());
}

throws a boost::bad_weak_ptr exception.

A couple of notes how this SphereNode is created (a Factory class)

boost::shared_ptr<INode> NodeFactory::createNode(const QString& type, QString tag)
{
...
QPluginLoader loader(filesPlugin_[i]);
boost::shared_ptr<QObject> plugin(loader.instance());
boost::shared_ptr<INode> iNodePlugin = boost::shared_dynamic_cast<INode>(plugin);
return iNodePlugin;
}

Any ideas?

Perhaps it is this line:

boost::shared_ptr<INode> iNodePlugin = boost::shared_dynamic_cast<INode>(plugin);

Which should be replaced by:

boost::shared_ptr<INode> iNodePlugin = dynamic_cast<INode*>(loader.instance())->shared_from_this();

Maybe it has something to do with:

boost::shared_ptr<QObject> plugin(loader.instance());

Here plugin takes ownership of the returned instance. However, the Qt documentation states that the instance will be automatically freed by the QPluginLoader upon destruction.

However, this would rather cause a segfault (undefined behavior) than a regular boost::bad_weak_ptr exception.

If you want to prevent this, you can specify a null_deleter that will do nothing when the reference counter reachs 0.


Are you calling shared_from_this() from either a constructor or a destructor (directly or indirectly) ?

If so, there is your problem.

When you're in the constructor, the object is not fully created yet, so having a shared_ptr to it is invalid.

To avoid this issue, you can get your shared_ptr to the object in a factory method (that you already have anyway), when the object was succesfully constructed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM