不为 shared_ptr 派生类调用析构函数

贝尔哈吉塞勒姆 TALEL

我想实现用于所有程序Mediator设计模式shared_ptr

这是Mediator interface

class Mediator
{
    public:
        Mediator(){ print("Mediator()"); }
        virtual void Notify(std::shared_ptr<BaseComponent> sender) const = 0;
};

这是ExampleMediator

class ExampleMediator : public Mediator
{
    private:
        std::shared_ptr<ExampleComponent> eC;
    public:
        void Notify(std::shared_ptr<BaseComponent> sender) const override {
            print("From Example Mediator");
        }
        void setExampleComponent(std::shared_ptr<ExampleComponent> eC_){
            eC = eC_;
        }
};

ExampleMediator具有共享指针ExampleComponent和设置它的方法。

这是基类BaseComponent

class BaseComponent
{
    protected:
        std::shared_ptr<Mediator> m;

    public:
        BaseComponent() { print("BaseComponent()"); }
        ~BaseComponent() { print("~BaseComponent()"); }
        void setMediator(std::shared_ptr<Mediator> m_){ m = m_; }
};

BaseComponent具有共享指针ExampleMediator和设置它的方法。

这是ExampleComponent

class ExampleComponent: public BaseComponent
{
    public:
        ExampleComponent(){ print("ExampleComponent()"); }
        ~ExampleComponent(){ print("~ExampleComponent()"); }
        void doSomethingOnDerived(){ print("ExampleComponent job");}
};

主要功能:

int main()
{

    // Create the mediator
    auto mM = std::make_shared<ExampleMediator>();
    
    // Create the component
    auto eC = std::make_shared<ExampleComponent>();
    eC->setMediator(mM);
    
    // Set the component in the mediator
    mM->setExampleComponent(eC);
}

输出是:

Mediator()
BaseComponent()
ExampleComponent()

如果我删除该行mM->setExampleComponent(eC);,则会调用构造函数。Compiler Explorer 中的实时代码:https : //godbolt.org/z/E5ofEPGen

我的目标是将组件用作共享指针而不是原始指针,中介器也是如此。

导致此问题的原因是什么?

谢谢。

埃罗里卡

导致此问题的原因是什么?

当指针是指向资源的最后一个所有者时,共享指针会破坏其拥有的资源。当局部变量eC在 返回时被销毁时main,还有另一个所有者,mM.eC因此资源不会被销毁。同样,当本地mM被销毁时,其资源仍为之前拥有的资源所拥有eC

当您拥有资源时,我们通常认为所有者“依赖”于该资源。如果我们将对象视为节点,将依赖关系视为边,我们会得到一个有向图。此依赖关系图不应有循环,因为这通常会导致您遇到的问题。

使用共享指针,打破循环的一种方法是削弱一个节点的所有权。这可以通过使用弱指针而不是共享指针来完成。请注意,您必须小心处理弱拥有资源在其依赖者之前被销毁的情况。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从未调用过的shared_ptr对象的析构函数

std :: shared_ptr为null但不为空

从shared_ptr <T>派生

提升shared_ptr和派生类

shared_ptr <Base>和派生类中的对象

为什么std :: shared_ptr两次调用我的析构函数?

通过类析构函数中的重置成员shared_ptrs解决C ++ 11 shared_ptr循环参考?

基类unique_ptr到派生类shared_ptr

从基类析构函数调用派生类方法

确保抽象低音类是shared_ptr

使用 shared_ptr 的矩阵类内容?

移动 std::shared_ptr 的函数声明

为什么要调用派生类的析构函数?

如果未使用shared_ptr定义虚拟析构函数,有什么好处?

具有shared_ptr的成员的C ++析构函数顺序

shared_ptr析构函数,复制和不完整类型

对链接列表使用shared_ptr可以在析构函数中提供stackoverflow

我可以通过vector <shared_ptr <BaseClass >>循环时以某种方式调用派生类方法吗?

来自抽象类的unique_ptr的shared_ptr

将shared_ptr的向量复制到抽象基的派生类

无法使用BaseClass的shared_ptr访问派生类的成员

shared_ptr 和 unique_ptr 构造函数

shared_ptr:在基类的shared_ptr中复制时,引用计数是否增加?

将std :: shared_ptr <T>传递给采用std :: shared_ptr <const T>的函数?

shared_ptr的静态成员函数make_shared

是否可以将const unique_ptr引用(派生类)转换为shared_ptr(基类)

当在C ++中获得指向基类的指针时,为什么不为派生类对象调用重载函数?

使用shared_ptr时需要实现析构函数,复制构造函数,赋值运算符

如何在具有受保护的析构函数和公共销毁方法的3d派对类上使用shared_ptr