我想在所有程序中使用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
之前拥有的资源。
当你拥有一个资源时,我们通常认为所有者是"依赖的"。在资源上。如果把对象看作节点,把依赖关系看作边,就得到了一个有向图。这个依赖关系图不应该有循环,因为这通常会导致您遇到的问题。
对于共享指针,打破循环的一种方法是削弱一个节点的所有权。这可以通过使用弱指针而不是共享指针来实现。请注意,您必须小心处理弱拥有的资源在其依赖资源之前被销毁的情况。