代码之家  ›  专栏  ›  技术社区  ›  Kumar Roshan Mehta

使用bad_weak_ptr从中启用共享失败

  •  1
  • Kumar Roshan Mehta  · 技术社区  · 1 年前

    我正在尝试学习weak_ptr和enable_shared_from_this,在这里,我想要 Component 将指针指向 Mediator 调解员 了解 组成部分 。我不明白为什么此代码失败 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;
    }
    
    1 回复  |  直到 1 年前
        1
  •  0
  •   Ted Lyngmo    1 年前

    当你打电话 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
    
    推荐文章