欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > std::weak_ptr应用于观察者模式的示例

std::weak_ptr应用于观察者模式的示例

2025/6/10 1:07:29 来源:https://blog.csdn.net/weixin_41761608/article/details/143865969  浏览:    关键词:std::weak_ptr应用于观察者模式的示例

在 C++ 中,std::weak_ptr 是一个智能指针,用来观察由 std::shared_ptr 所管理的对象,而不增加该对象的引用计数。它通常用于避免 循环引用强引用计数的增长,特别在实现观察者模式时,weak_ptr 可以帮助观察者避免不必要的对象生命周期延长。

以下是如何使用 std::weak_ptr 来实现一个简单的观察者模式的示例。

观察者模式简介

观察者模式是一种行为设计模式,其中一个对象(主题或发布者)维护一组依赖对象(观察者),并在状态变化时通知这些观察者。主题对象的生命周期通常较长,而观察者对象的生命周期通常较短,使用 weak_ptr 可以确保观察者在主题对象销毁时不会导致内存泄漏。

示例:使用 weak_ptr 实现观察者模式

下面是一个简单的例子,其中我们有一个 Subject 类(主题),它可以注册多个 Observer(观察者)。每个观察者是通过 std::weak_ptr 来持有的,避免循环引用。

1. 定义 ObserverSubject
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>class Observer {
public:virtual void update(int value) = 0;virtual ~Observer() = default;
};class Subject {
private:std::vector<std::weak_ptr<Observer>> observers;public:void addObserver(const std::shared_ptr<Observer>& observer) {observers.push_back(observer);}void removeObserver(const std::shared_ptr<Observer>& observer) {observers.erase(std::remove_if(observers.begin(), observers.end(),[&](const std::weak_ptr<Observer>& o) { return o.lock() == observer; }), observers.end());}void notify(int value) {for (auto& weakObserver : observers) {if (auto observer = weakObserver.lock()) {  // 如果观察者仍然存在observer->update(value);}}}
};
2. 定义具体的 Observer 实现
class ConcreteObserver : public Observer {
private:std::string name;public:ConcreteObserver(const std::string& name) : name(name) {}void update(int value) override {std::cout << "Observer " << name << " received update with value: " << value << std::endl;}
};
3. 使用 SubjectObserver
int main() {// 创建主题对象std::shared_ptr<Subject> subject = std::make_shared<Subject>();// 创建观察者对象std::shared_ptr<ConcreteObserver> observer1 = std::make_shared<ConcreteObserver>("Observer1");std::shared_ptr<ConcreteObserver> observer2 = std::make_shared<ConcreteObserver>("Observer2");// 注册观察者subject->addObserver(observer1);subject->addObserver(observer2);// 通知观察者subject->notify(10);  // 所有观察者都会接收到通知// 移除一个观察者subject->removeObserver(observer1);// 通知剩余的观察者subject->notify(20);  // 只有 Observer2 会接收到通知// observer2 会自动销毁,而 observer1 的析构函数不会被触发return 0;
}

解释

  1. 观察者和主题:

    • Observer 是一个抽象类,定义了 update 方法,所有具体的观察者类都需要实现该方法。
    • Subject 是主题类,管理所有的观察者。它使用 std::weak_ptr<Observer> 来存储观察者,以避免观察者对象的生命周期被 Subject 锁住。
  2. weak_ptr 使用:

    • Subject 中,观察者是通过 std::weak_ptr<Observer> 存储的。weak_ptr 不会增加观察者的引用计数,避免了循环引用的问题。使用时,需要调用 lock() 方法来获取一个有效的 shared_ptr,如果观察者已经被销毁(引用计数为 0),lock() 会返回一个空指针。
  3. 观察者的生命周期管理:

    • main 函数中,我们创建了两个观察者对象,并注册到主题对象中。当我们通过 subject->notify() 向观察者发送通知时,只有有效的观察者会接收到通知。
    • 当一个观察者被从 Subject 中移除后,它将不再接收到通知。
    • std::weak_ptr 确保即使观察者对象在通知过程中销毁,它也不会阻止观察者对象的销毁。
  4. 移除观察者:

    • removeObserver 方法移除了特定的观察者。我们使用 std::remove_if 来从观察者列表中删除对应的观察者。如果该观察者已经被销毁,lock() 将返回 nullptr,该观察者将不会再被通知。

总结

使用 std::weak_ptr 可以有效地避免观察者模式中的循环引用问题,避免因为观察者持有主题对象的 shared_ptr 而导致无法销毁的问题。在这个示例中,Subject 类管理观察者的生命周期,而每个 Observer 使用 weak_ptr 观察主题对象,从而实现了避免循环引用和内存泄漏的功能。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词