shared_ptr派生类没有调用析构函数



我想在所有程序中使用shared_ptr来实现Mediator设计模式。

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);行,则调用构造函数。编译器资源管理器中的实时代码:https://godbolt.org/z/E5ofEPGen

我的目标是使用组件作为共享指针,而不是原始指针,与中介器相同。

这个问题的原因是什么?

谢谢。

这个问题的原因是什么?

当共享指针是指向该资源的最后一个所有者时,该指针将销毁该资源。当局部变量eC在返回main时被销毁时,仍然存在另一个所有者mM.eC,因此资源不会被销毁。同样,当本地mM被销毁时,它的资源仍然属于eC之前拥有的资源。

当你拥有一个资源时,我们通常认为所有者是"依赖的"。在资源上。如果把对象看作节点,把依赖关系看作边,就得到了一个有向图。这个依赖关系图不应该有循环,因为这通常会导致您遇到的问题。

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

最新更新