简体   繁体   English

使用 (this) 注册到观察者的共享指针

[英]Shared pointer using (this) registering to an observer

I am having a problem trying to use a shared pointer from a class that wants to register to an observer (using ) here is the example.我在尝试使用来自想要注册到观察者的类的共享指针时遇到问题(使用 ),这是示例。

Observer.hpp观察者.hpp

class Observer {
virtual void update() = 0;
}

Consumer.hpp消费者.hpp

class Consumer : public Observer {
virtual void update() override;
}

Consumer.cpp消费者.cpp

class Consumer {
***

THIS IS NOT WORKING - How to do it using shared pointers??这不起作用 - 如何使用共享指针来做到这一点?


register.registerObserver(std::make_shared<Observer>(this));
}

Register.cpp注册.cpp

class Register {
void registerObserver(const std::shared_ptr<Observer>& observer);
}

You should never usemake_shared or otherwise construct a shared_ptr from this.您永远不应该使用make_shared或以其他方式从中构造shared_ptr

Additionally never combine memory management techniques unless you're absolutely sure you know and understand completely what you are doing.此外,永远不要结合内存管理技术,除非您绝对确定您完全了解并理解您在做什么。

If you really need a shared_ptr referencing the current object you should instead construct the object as a shared_ptr the first time and have the class inherit enable_shared_from_this .如果你真的需要一个引用当前对象的shared_ptr ,你应该在第一次将对象构造为shared_ptr并让类继承enable_shared_from_this

After that when you need the shared pointer use shared_from_this之后,当您需要共享指针时,请使用shared_from_this

Since you have a this you have already constructed your object and using the direct pointer to create another shared pointer from it will result in your reference getting destroyed as soon as one of your shared_ptr references reach 0, leaving the other having a invalid reference.由于您有一个 this ,您已经构建了您的对象,并且使用直接指针从它创建另一个共享指针将导致您的引用在您的一个 shared_ptr 引用达到 0 时立即被破坏,而使另一个引用无效。

Always remember that when talking about shared pointers, what you are semantically trying to convey is about the pointed-to object ownership: is it an unique ownership?永远记住,在谈论共享指针时,您在语义上试图传达的是关于指向对象的所有权:它是唯一的所有权吗? Is it shared?是共享的吗? Is it just for using the pointed-to object state?是否仅用于使用指向对象状态?

In particular, the Observer pattern defines two interfaces.特别是,观察者模式定义了两个接口。 The observed subject must have some kind of reference to the observers (so it can use their callback() to update/notify them).被观察的主体必须对观察者有某种引用(因此它可以使用他们的回调()来更新/通知他们)。 On the other hand, the observer must have a reference to the observed subject so it can ask information when its state changes (assuming that the observer is listening for changes in the observed subject).另一方面,观察者必须拥有对被观察主体的引用,以便在其状态发生变化时询问信息(假设观察者正在监听被观察主体的变化)。 So, these references in each object might be just weak_ptrs, because we are not interested in controlling the lifetime of the pointed-to objects.因此,每个对象中的这些引用可能只是weak_ptrs,因为我们对控制指向对象的生命周期不感兴趣。

As an example, lets say we have a data producer object (the one which is going to be observed), and a data printer object (the one observing for new data made by the producer).例如,假设我们有一个数据生产者对象(将被观察的对象)和一个数据打印机对象(观察生产者生成的新数据的对象)。 So, the code might look like this:因此,代码可能如下所示:

#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>

// Classes have default constructors and destructors.
class DataPrinter;

class DataProducer
{
 public:

    std::string data_{"Data"};

    void subscribeObserver(std::weak_ptr<DataPrinter> dataPrinter_ptr);
    void notifyObservers();

 private:
    std::weak_ptr<DataPrinter> dataPrinter_ptr_;
};

class DataPrinter
{
 public:

    explicit DataPrinter(std::weak_ptr<DataProducer> dataProducer);
    void update();

 private:
    std::weak_ptr<DataProducer> dataProducer_ptr_;
};

// ------------------------------------------------------------------------
// DataProducer definitions.
void DataProducer::subscribeObserver(std::weak_ptr<DataPrinter> dataPrinter_ptr)
{
    dataPrinter_ptr_ = std::move(dataPrinter_ptr);
}

void DataProducer::notifyObservers()
{
    auto dp_ptr = dataPrinter_ptr_.lock();
    if (dp_ptr) dp_ptr->update();
}

// ------------------------------------------------------------------------
// DataPrinter definitions.
DataPrinter::DataPrinter(std::weak_ptr<DataProducer> dataProducer) : dataProducer_ptr_(std::move(dataProducer))
{
    auto dp_ptr = dataProducer.lock();
    if (dp_ptr) dp_ptr->subscribeObserver(std::shared_ptr<DataPrinter>(this));
}

void DataPrinter::update()
{
    auto dp_ptr = dataProducer_ptr_.lock();
    if (dp_ptr) std::cout << dp_ptr->data_ << std::endl;
}

// ------------------------------------------------------------------------
int main()
{
    std::shared_ptr<DataProducer> dataProducer = std::make_shared<DataProducer>();
    std::shared_ptr<DataPrinter> dataPrinter = std::make_shared<DataPrinter>(dataProducer);

    dataProducer->notifyObservers();

    return EXIT_SUCCESS;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM