我正在尝试学习weak_ptr和enable_shared_from_this,在这里,我希望
Component
有指向Mediator
和Mediator
的指针来了解Component
。我不明白为什么这段代码会失败并显示 bad_weak_ptr
。如何解决这个问题?我明白,对于shared_from_this,它必须由shared_ptr拥有,我认为这里是正确的,但它仍然失败,原因是什么?
#include <iostream>
#include <string>
#include <memory>
using namespace std;
class BaseComponent;
class Mediator: public enable_shared_from_this<Mediator> {
public:
virtual void Notify(std::string event) const = 0;
};
/**
* The Base Component provides the basic functionality of storing a mediator's
* instance inside component objects.
*/
class BaseComponent : public enable_shared_from_this<BaseComponent> {
protected:
weak_ptr<Mediator> mediator_;
public:
BaseComponent() : mediator_() {
}
void set_mediator(shared_ptr<Mediator> mediator) {
mediator_ = mediator;
}
};
/**
* Concrete Components implement various functionality. They don't depend on
* other components. They also don't depend on any concrete mediator classes.
*/
class Component1 : public BaseComponent {
public:
void DoA() {
std::cout << "Component 1 does A.\n";
if(auto w_mediator_ = mediator_.lock())
w_mediator_->Notify("A");
}
void DoB() {
std::cout << "Component 1 does B.\n";
if(auto w_mediator_ = mediator_.lock())
w_mediator_->Notify("B");
}
};
class Component2 : public BaseComponent {
public:
void DoC() {
std::cout << "Component 2 does C.\n";
if(auto w_mediator_ = mediator_.lock())
w_mediator_->Notify("C");
}
void DoD() {
std::cout << "Component 2 does D.\n";
if(auto w_mediator_ = mediator_.lock())
w_mediator_->Notify("D");
}
};
/**
* Concrete Mediators implement cooperative behavior by coordinating several
* components.
*/
class ConcreteMediator : public Mediator {
private:
shared_ptr<Component1> component1_;
shared_ptr<Component2> component2_;
public:
ConcreteMediator(shared_ptr<Component1> c1, shared_ptr<Component2> c2) : component1_(c1), component2_(c2) {
component1_->set_mediator(shared_from_this());
component2_->set_mediator(shared_from_this());
}
void Notify(std::string event) const override {
if (event == "A") {
std::cout << "Mediator reacts on A and triggers following operations:\n";
component2_->DoC();
}
if (event == "D") {
std::cout << "Mediator reacts on D and triggers following operations:\n";
component1_->DoB();
component2_->DoC();
}
}
};
/**
* The client code.
*/
void ClientCode() {
auto c1 = make_shared<Component1>();
auto c2 = make_shared<Component2>();
auto mediator = make_shared<ConcreteMediator>(c1, c2);
std::cout << "Client triggers operation A.\n";
c1->DoA();
std::cout << "\n";
std::cout << "Client triggers operation D.\n";
c2->DoD();
}
int main() {
ClientCode();
return 0;
}
当您调用
share_from_this
时,该对象必须由 shared_ptr
管理。
它尚未由构造函数内的
shared_ptr
管理,但您可以将该代码移出并将其放入一个单独的函数中,并在构造后调用 mediator
。
class ConcreteMediator : public Mediator {
public:
ConcreteMediator(shared_ptr<Component1> c1, shared_ptr<Component2> c2)
: component1_(c1), component2_(c2) {}
void set_mediators() {
component1_->set_mediator(shared_from_this());
component2_->set_mediator(shared_from_this());
}
};
auto mediator = make_shared<ConcreteMediator>(c1, c2);
mediator->set_mediators(); // this will work