问题描述
我正在尝试学习c ++,因此,我尝试实现《游戏编程模式》一书中的观察者模式,但是我总是遇到细分错误。
搜索周围环境我发现当程序尝试访问未分配的内存时发生分段错误。所以我尽力修复它,但是不能。有人可以帮助我吗?
这是我的代码:
Observer.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
Achievements.cpp
#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
Subjects.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进行回复。 @darcamo有效。我不知道为什么它被声明为指针。
我已解决此问题,因此,如果其他人也有同样的疑问,请在下面进行检查: 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;
}