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
class Observer {
virtual void update() = 0;
}
Consumer.hpp
class Consumer : public Observer {
virtual void update() override;
}
Consumer.cpp
class Consumer {
***
THIS IS NOT WORKING - How to do it using shared pointers??
register.registerObserver(std::make_shared<Observer>(this));
}
Register.cpp
class Register {
void registerObserver(const std::shared_ptr<Observer>& observer);
}
You should never usemake_shared or otherwise construct a shared_ptr from this.
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 .
After that when you need the shared pointer use 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.
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.
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.