试图实现观察者模式并得到分割错误(请帮助)c++



我正在努力学习c++,所以我试图实现《游戏编程模式》一书中的观察者模式,但我总是遇到Segmentation Fault。

在附近搜索时,我发现程序试图访问未分配的内存时会发生分段故障。所以我努力想把它修好,但我做不到。有人能帮我吗?

这是我的代码:

观察员.h

#ifndef OBSERVER_H
#define OBSERVER_H
#include "EntityAndEvent.h"
#include "Subjects.h"
class Observer
{
private:
Observer* next_;
public:
Observer()
: next_(nullptr)
{}
virtual void onNotify(const Entity& entity, Event::Type event) = 0;

// Other stuff...
friend class Subjects;
};
#endif

成就.pp

#ifndef ACHIEVEMENTS_CPP
#define ACHIEVEMENTS_CPP
#include "Observer.h"
#include <vector>
class Achievements : public Observer
{
public:
enum Type{
FELL_OFF,
AWAKE_ON
};
private:
std::vector<Type> done{};
public:
virtual void onNotify(const Entity&, Event::Type);
void unlock(Achievements::Type);
void printDone();
};
void Achievements::onNotify(const Entity& entity, const Event::Type event) 
{
switch (event)
{
case Event::Type::ENTITY_FELL:
if(entity.isHero())
unlock(Achievements::Type::FELL_OFF);
break;
case Event::Type::ENTITY_AWAKE:
if(entity.isHero())
unlock(Achievements::Type::AWAKE_ON);
break;

default:
break;
}
};
void Achievements::unlock(Achievements::Type achiev) 
{
done.push_back(achiev);
}
void Achievements::printDone() 
{
// assert(done.size());
for(size_t i{0}; i < done.size(); i++)
{
std::cout << done[i] << "n";
}
};

EntityAndEvent.cpp(我创建它只是为了与观察者和受试者合作(

#ifndef ENTITY_AND_EVENT_H
#define ENTITY_AND_EVENT_H
class Entity
{
public:
inline const bool isHero() const {return true;}
};
class Event
{
public:
enum Type{
ENTITY_FELL,
ENTITY_AWAKE
};
};
#endif

受试者.h

#ifndef SUBJECT_H
#define SUBJECT_H
#include "Observer.h"
#include <vector>
class Observer;
class Subjects
{
private:
// when implements this, prefer to use linked list or another optimized algorithms
Observer* head_{};
protected:
void notify(const Entity& Entity, Event::Type event);

public:
Subjects() : head_(NULL)
{};
~Subjects() {}
void addObserver(Observer* observer);

// const int getNumObs() const {return num_obs_;}
};
#endif

Subjects.cpp

#include "Subjects.h"
#include <cassert>
void Subjects::notify(const Entity& entity, Event::Type event) 
{
Observer* observer = head_;
while (observer != NULL)
{
observer->onNotify(entity, event);
observer = observer->next_;
};
};
void Subjects::addObserver(Observer* observer) 
{
if (head_ != nullptr)
observer->next_ = head_;
head_ = observer;
};

Physics.cpp(我创建这个只是为了填充主题(

#ifndef PHYSICS_H
#define PHYSICS_H
#include "Subjects.h"
#include "EntityAndEvent.h"
class Physics: public Subjects
{
private:

public:
void update(const Entity& entity)
{
if (entity.isHero())
{
notify(entity, Event::Type::ENTITY_AWAKE);
};
};
};
#endif

main.cpp

#include "Observer.h"
#include "Achievements.h"
#include "Achievements.cpp"
#include "EntityAndEvent.h"
#include "Physics.h"
#include "Subjects.h"
#include "Subjects.cpp"
int main()
{
Physics *p{};
Entity e{};
Achievements *achiev{};
p->addObserver(achiev);
p->update(e);

return 0;
}

使用Physics *p{};,您正在声明一个指针,但它当前未指向有效对象(此处初始化为nullptr(。因此,调用p->addObserver导致分段错误。您应该能够通过在调试器中运行程序来确认这一点。

你为什么在这里用指针?将Physics *p{};更改为Physics p{};


免责声明:由于您的代码绝对不是一个最小的例子,我没有查看整个代码,甚至没有尝试编译它。我只是发布了一个答案,因为main函数中有一个明显的错误(使用了无效指针(,导致了分段错误。

首先,tks用于回复@达卡莫,这是有效的。我不知道为什么它被声明为指针。

我解决了这个问题,所以如果其他人也有同样的疑问,请在下面进行检查:main.cpp

#include "Observer.h"
#include "Achievements.h"
#include "EntityAndEvent.h"
#include "Physics.h"
#include "Subjects.h"
int main()
{
Physics p{};
Entity e{};
Achievements achiev{};
Observer* ptr_achiev{&achiev};
p.addObserver(ptr_achiev);
p.update(e);

return 0;
}

最新更新