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 (e.g. 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. E.g. 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?

Answers


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.


Need Your Help

TeeChart Pro 2014 for delphi 2007 Trend with barseries

delphi vcl teechart trend

I'm using a TDBChart to display 3 barseries of the data. Can you point me to a good example of adding a trend line to each barseries? The example that comes with TeeChart download is not at all hel...

How would you implement Controller in Javascript? (inside of self-made MVC)

javascript model-view-controller

I want to implement MVC pattern in JavaScript, but I have a problem with Controller implementation.