如何在不是shared_ptr的成员中使用shared_ptr?

时间:2010-09-30 10:36:28

标签: c++ boost shared-ptr

我正在研究几个类,我想知道如何在我的应用程序类中使用普通成员,其中成员需要使用shared_from_this()?

这里有一些代码来澄清我的意思(见评论)

class Observable {
public:
    void addObserver(boost::shared_ptr<Observer> observer) {
        // add to a list
    }
};

class Observer {
public:
    virtual void onUpdate() = 0;
};

class MyObservableType : public Observable {
};

class ApplicationModel : public Observer {
private:
    MyObservableType mot;
public:
    void setup() {
    // how do I pass this as a boost::shared_ptr, as ApplicationModel is not 
    // a boost::shared_ptr in the Application class this using a call to 
    // "shared_from_this()" (and inheriting public shared_from_this<ApplicationModel>
        mot.addObserver([shared_from_this]) 
    }
};

class Application {
private:
    ApplicationModel model;
public:
    void setup() {
        model.
    }
};

2 个答案:

答案 0 :(得分:1)

您有三个解决此问题的方法:

第一个解决方案:强制应用程序通过将其构造函数设为私有来创建shared_ptr。对于从enable_shared_from_this

派生的任何类,我建议这样做
class ApplicationModel : public Observer, public boost::enable_shared_from_this<ApplicationModel> {
private:
    ApplicationModel(); // private constructor

    MyObservableType mot;
public:
    // an instance of this class can only be created using this function
    static boost::shared_ptr<ApplicationModel> buildApplicationModel() {
        return boost::make_shared<ApplicationModel>();
    }

    void setup() {
        mot.addObserver(shared_from_this()) ;
    }
};

第二个解决方案:更改您的代码设计。 您不应该要求ApplicationModel将自己注册到Observable,而是自己完成。这样ApplicationModel不执行任何操作,但如果其所有者想要调用addObservable,则必须创建shared_ptr。这或多或少被称为dependency injection

class Application {
private:
    boost::shared_ptr<ApplicationModel> model;
    MyObservableType mot;
public:
    void setup() {
        model = boost::make_shared<ApplicationModel>();
        mot.addObserver(model);
    }
};

编辑:第三个解决方案:使用虚拟的shared_ptr,如下所示:

class ApplicationModel : public Observer {
private:
    boost::shared_ptr<ApplicationModel> myself;

    MyObservableType mot;

public:
    void setup() {
        mot.addObserver(myself) ;
    }

    ApplicationModel() {
        myself = boost::shared_ptr<ApplicationModel>(this, [](ApplicationModel*) {});
    }

    ~ApplicationModel() {
        mot.removeObserver(myself);
        assert(myself.unique());
    }
};

我的想法是创建一个shared_ptr到this并告诉shared_ptr不要调用析构函数(这里我使用一个空的lambda函数,但你可以轻松地创建一个内联结构)。这是一个黑客,你不应该这样做。

答案 1 :(得分:0)

你做不到。 shared_from_this()要求您的对象通过shared_ptr动态分配。

请参阅this page of the documentation,其中说明:

  

需要:enable_shared_from_t这必须是T的可访问基类。*这必须是T类型的实例t的子对象。必须存在至少一个拥有t的shared_ptr实例p。

因此,您需要更改代码,以使ApplicationModel的任何实例由shared_ptr“拥有”。例如:

class ApplicationModel : 
    public Observer,
    public boost::enable_shared_from_this<ApplicationModel>
{
    //...
    void setup() {
        mot.addObserver(shared_from_this());
    }
};

class Application {
private:
    // Application object must initialize this somewhere
    boost::shared_ptr<ApplicationModel> model;  
    //...
};