shared_ptr 派生 class 不调用析构函数
Destructor is not called for shared_ptr derived class
我想为所有程序使用 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
的共享指针和设置它的方法。
这是基础classBaseComponent
:
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
我的目标是将组件用作共享指针而不是原始指针,对于 Mediator 也是如此。
导致此问题的原因是什么?
谢谢。
What can be the cause for this issue?
当指针是指向资源的最后一个所有者时,共享指针会销毁它们拥有的资源。当局部变量 eC
在 main
的 return 被销毁时,还有另一个所有者 mM.eC
所以资源不会被销毁。同样,当本地mM
被销毁时,它的资源仍然是eC
之前拥有的资源。
当您拥有资源时,我们通常认为所有者“依赖”该资源。如果我们将对象视为节点,将依赖关系视为边,我们将得到一个有向图。此依赖关系图不应有循环,因为这通常会导致您遇到的问题。
使用共享指针,打破循环的一种方法是削弱一个节点的所有权。这可以通过使用弱指针而不是共享指针来完成。请注意,您必须小心处理弱拥有资源在其依赖者之前被销毁的情况。
我想为所有程序使用 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
的共享指针和设置它的方法。
这是基础classBaseComponent
:
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
我的目标是将组件用作共享指针而不是原始指针,对于 Mediator 也是如此。
导致此问题的原因是什么?
谢谢。
What can be the cause for this issue?
当指针是指向资源的最后一个所有者时,共享指针会销毁它们拥有的资源。当局部变量 eC
在 main
的 return 被销毁时,还有另一个所有者 mM.eC
所以资源不会被销毁。同样,当本地mM
被销毁时,它的资源仍然是eC
之前拥有的资源。
当您拥有资源时,我们通常认为所有者“依赖”该资源。如果我们将对象视为节点,将依赖关系视为边,我们将得到一个有向图。此依赖关系图不应有循环,因为这通常会导致您遇到的问题。
使用共享指针,打破循环的一种方法是削弱一个节点的所有权。这可以通过使用弱指针而不是共享指针来完成。请注意,您必须小心处理弱拥有资源在其依赖者之前被销毁的情况。