启用共享失败并出现 bad_weak_ptr

问题描述 投票:0回答:1

我正在尝试学习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;
}
c++ c++14 shared-ptr
1个回答
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
© www.soinside.com 2019 - 2024. All rights reserved.