我打算实现一个线程安全的观察者模式。但是在测试下面的代码时我得到了一个coredump:
要运行代码,只需编译: g ++ --std = c ++ 11 code.cpp
请帮助我找到其中发生的问题:
#include <memory>
#include <vector>
#include <mutex>
#include <algorithm>
#include <iostream>
class Observable;
class CurrentConditionDisplay;
class Observer : std::enable_shared_from_this<Observer> {
public:
void observe(Observable* s);
virtual ~Observer() ;
virtual void update(float temp, float humidity, float pressure) = 0;
private:
Observable *sub_;
};
class Observable {
protected :
class MutexGuard {
public:
MutexGuard(std::mutex* mtx) : gmtx_(mtx) {
this->lock();
}
void lock () const {
gmtx_->lock();
}
void unlock () const {
gmtx_->unlock();
}
~MutexGuard() {
this->unlock();
}
private:
std::mutex* gmtx_ ;
};
#define MutextGuard(x) error "Missing Guard Obect"
public:
typedef std::weak_ptr<Observer> ObWeakPtr;
typedef std::shared_ptr<Observer> ObSharedPtr;
virtual ~Observable() {
oblist_.clear();
}
void registerObserver(std::weak_ptr<Observer> ob);
//void removeObserver(std::weak_ptr<Observer> ob);
void notifyObservers();
protected:
virtual void notify(std::shared_ptr<Observer> sptr) = 0;
typedef std::vector<std::weak_ptr<Observer>> ObList;
ObList oblist_;
std::mutex mtx_;
};
void Observer::observe(Observable* s) {
sub_ = s;
sub_->registerObserver(shared_from_this());
}
Observer::~Observer() {
// sub_->removeObserver(shared_from_this());
}
void Observable::notifyObservers() {
MutexGuard m(&mtx_);
for (ObList::iterator it = oblist_.begin();
it != oblist_.end(); ++it) {
std::shared_ptr<Observer> sptr = it->lock();
if (sptr) {
this->notify(sptr);
} else {
oblist_.erase(it);
}
}
}
void Observable::registerObserver(std::weak_ptr<Observer> ob) {
MutexGuard m(&mtx_);
//if (oblist_.end()
// != std::find (oblist_.begin(), oblist_.end(), ob)) {
oblist_.push_back(ob);
//}
}
/*
void Observable::removeObserver(std::weak_ptr<Observer> ob) {
MutexGuard m(&mtx_);
ObList::iterator it = oblist_.end();
if ( oblist_.end() !=
(it = std::find(oblist_.begin(), oblist_.end(), ob)) ) {
oblist_.erase(it);
}
}*/
class WeatherData : public Observable {
public:
void measurementsChanged(float temp, float humi, float pres) {
bool changed = false;
temp_ == temp ? temp_ = temp, changed |= true : 1;
humi_ == humi ? humi_ = humi, changed |= true : 1;
pres_ == pres ? pres_ = pres, changed |= true : 1;
if (changed) {
this->notifyObservers();
}
}
void notify(std::shared_ptr<Observer> sptr) {
sptr->update(temp_, humi_, pres_);
}
private:
float temp_; // temperature
float humi_; // humidity
float pres_; // pressure
};
class CurrentConditionDisplay : public Observer {
public:
void update(float temp, float humi, float pres) {
temp_ = temp;
humi_ = humi;
display();
}
void display() {
std::cout << "Current Condition: " << temp_
<< "'F degrees and " << humi_ << "\% humidity";
}
private:
float temp_;
float humi_;
};
int main() {
WeatherData* w = new WeatherData();
CurrentConditionDisplay * cur = new CurrentConditionDisplay();
cur->observe(w);
w->measurementsChanged(1.0, 1.0, 1.0);
return 0;
}
答案 0 :(得分:2)
这是问题所在:
CurrentConditionDisplay * cur = new CurrentConditionDisplay();
要使用shared_from_this()
,对象必须由shared_ptr
拥有,但您的对象不是。
您应该使用:
auto cur = std::make_shared<CurrentConditionDisplay>();