Trying to implement Observer Patterns and got Segmentation Fault (pls help) c++ - gcc

I'm trying to learn c++ so, I try to implement the observer patterns from the book Game Progamming Patterns but I'm always getting Segmentation Fault.
Searching arround I saw that Segmentation fault happens when a program try to access a non allocated memory. So I tried hard to fix it, but I can't. Someone can help me?
Here is my code:
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 (i create this just to work with observer and subjects)
#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 (i create this just to populates the subject)
#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;
}

With Physics *p{}; you are declaring a pointer, but it currently does not point to a valid object (it is being initialized as nullptr here). Therefore, calling p->addObserver results in a segmentation fault. You should be able to confirm this by running the program in a debugger.
Why are you using a pointer here? Change Physics *p{}; to Physics p{};.
Disclaimer: Since your code is definitely not a minimum example I didn't look into the whole code or even tried to compile it. I'm only posting an answer because there is a clear error in the main function (use of an invalid pointer) that results in a segmentation fault.

first, tks for the reply. #darcamo that works. I dont know why it was declared as pointer.
I fixed that, so if anyone else have the same doubt check below:
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;
}

Related

having difficulties to make a vector of polymorphic objects using shared_ptr and unique_ptr in C++ Visual studio 2019 Cmake project

For an exercise i need to build a vector of polymorphic objects and for some reason both shared and Unique ptr make linkage errors 2019 and 1120 when i use them. i have no option to use the old way of memory allocation with New and Delete so i have to make it work. i tried various of different syntax options for doing this and still with no luck.
*note:
we use Cmake to bind the project together in visual studio
and also we splitting the objects into header and cpp files.
here are my objects for now:
//This is the abstract base class
#pragma once
#include <string>
class Shape
{
public:
Shape() = default;
virtual ~Shape() = default;
virtual std::string get_name() = 0;
private:
};
These are the derived classes:
#pragma once
#include "Shape.h"
class Circle : public Shape
{
public:
Circle();
~Circle();
virtual std::string get_name() override;
private:
std::string m_name;
};
Cpp file:
#pragma once
#include "Circle.h"
Circle::Circle()
: m_name("Circle")
{
}
Circle::~Circle()
{
}
std::string Circle::get_name() override
{
return m_name;
}
another derived class:
#pragma once
#include "Shape.h"
class Rectangle : public Shape
{
public:
Rectangle();
~Rectangle();
virtual std::string get_name() override;
private:
std::string m_name;
};
Cpp file:
#pragma once
#include "Rectangle.h"
Rectangle::Rectangle()
: m_name ("Rectangle")
{
}
Rectangle::~Rectangle()
{
}
std::string Rectangle::get_name() override
{
return m_name;
}
this is the class that operates the program:
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include "Shape.h"
#include "Circle.h"
#include "Rectangle.h"
class Board
{
public:
Board();
~Board();
void run();
void objects_allocation();
private:
std::string m_string;
std::vector<std::shared_ptr<Shape>> m_gates;
};
Cpp file:
#pragma once
#include "Board.h"
Board::Board()
: m_string(" ")
{
}
Board::~Board()
{
}
void run()
{
while (m_string != "exit")
{
std::cin >> m_string;
}
std::cout << "Goodbye!" << std::endl;
}
void Board::Objects_allocation()
{
m_gates.push_back(std::make_shared <Circle>());
m_gates.push_back(std::make_shared <Rectangle>());
}
and here is my main function:
#pragma once
#include "Board.h"
int main()
{
Board board1;
board1.run();
return 0;
}
sincerely thank you if you could explain to me what went wrong here..
The Problem was in the Cmake file. now everything is working just like i wanted.

How to derive abstract template classes, with template-types as function parameters (C++11)

I've been assigned to write a class "binaryExpressionTree" which is derived from the abstract template class "binaryTreeType." binaryExpressionTree is of type String. As part of the assignment, I have to override these 3 virtual functions from binaryTreeType:
//Header File Binary Search Tree
#ifndef H_binaryTree
#define H_binaryTree
#include <iostream>
using namespace std;
//Definition of the Node
template <class elemType>
struct nodeType
{
elemType info;
nodeType<elemType> *lLink;
nodeType<elemType> *rLink;
};
//Definition of the class
template <class elemType>
class binaryTreeType
{
public:
virtual bool search(const elemType& searchItem) const = 0;
virtual void insert(const elemType& insertItem) = 0;
virtual void deleteNode(const elemType& deleteItem) = 0;
binaryTreeType();
//Default constructor
};
binaryTreeType<elemType>::binaryTreeType()
{
}
#endif
Here is what I have so far for binaryExpressionTree:
#define EXPRESSIONTREE_H
#include "binaryTree.h"
#include <iostream>
#include <string>
class binaryExpressionTree : public binaryTreeType<string> {
public:
void buildExpressionTree(string buildExpression);
double evaluateExpressionTree();
bool search(const string& searchItem) const = 0;
void insert(const string& insertItem) = 0;
void deleteNode(const string& deleteItem) = 0;
};
And here's binaryExpressionTree.cpp:
#include <string>
#include <cstring>
#include <stack>
#include <cstdlib>
#include <cctype>
#include "binaryExpressionTree.h"
#include "binaryTree.h"
using namespace std;
bool binaryExpressionTree::search(const string& searchItem) const {
return false;
}
void binaryExpressionTree::insert(const string& insertItem) {
cout << "this";
}
void binaryExpressionTree::deleteNode(const string& deleteItem) {
cout << "this";
}
Here's main.cpp:
#include <iostream>
#include <iomanip>
#include <fstream>
#include "binaryExpressionTree.h"
int main()
{
binaryExpressionTree mainTree = binaryExpressionTree(); //Error:[cquery] allocating an object of abstract class type 'binaryExpressionTree'
return 0;
}
The problem is, since binaryExpressionTree is a derived class of type String, it doesn't know what "elemType" means and I would need to change searchItem, insertItem and deleteItem
to string& objects. But once I do, the compiler no longer recognizes that I am overriding virtual functions (as I've changed their parameters), and declares binaryExpressionTree to be an abstract class. How do I work around this, so that I can override the functions and make binaryExpressionTree non-abstract?
Assuming the abstract class is defined like this:
template <typename elemType>
class binaryTreeType { ... }
You should define your class as follows:
class binaryExpressionTree : public binaryTreeType<String> { ... }
EDIT: original question was edited.
You are incorrectly declaring the overriding functions (inside binaryExpressionTree).
Your declaration is like this:
bool search(const string& searchItem) const = 0;
Such declaration creates a pure virtual method (because of = 0 at the end of the declaration. A pure virtual method (aka an abstract method) is a method which must be overridden by a deriving class. Thus, binaryTreeType declared its methods pure virtual, in order for you to implement, in binaryExpressionTree.
Classes which have abstract methods which are not implemented yet, cannot be instantiated - that is the error your compiler is generating.
Instead, you should declare your methods like this:
virtual bool search(const elemType& searchItem) const;
Such declaration creates regular virtual function, which would override the parent implementation (which is non-existent, at this case).
TL;DR - remove = 0.

How to write a C++ API class that will allow a user to register its own callback functions?

Let's say a user links his app against a library I wrote and I want to let him specify a callback function that I will call whenever an error occurs in my library. The implementation below works but I want to double check that I'm not missing something here:
Thread safety
DLL initialization issues
Public API considerations (I'm giving away a reference to an instance from the DLL is that OK?)
Anything that could be done better to hide implementation details from the public API?
errordispatcher.h:
#pragma once
#include <functional>
#include <memory>
#include <string>
namespace WE
{
class ErrorDispatcher
{
public:
ErrorDispatcher()
{}
explicit ErrorDispatcher(std::function<void(std::string)> user_func)
: error_callback_func{user_func}
{}
virtual ~ErrorDispatcher(){}
static ErrorDispatcher& getInstance()
{
return instance_;
}
void setErrorCallback(std::function<void(std::string)> user_func)
{
error_callback_func = nullptr;
if (user_func)
error_callback_func = user_func;
}
void dispatchError(std::string message)
{
if (error_callback_func)
error_callback_func(message);
}
private:
explicit ErrorDispatcher(const ErrorDispatcher&) = delete;
explicit ErrorDispatcher(ErrorDispatcher&&) = delete;
ErrorDispatcher& operator = (const ErrorDispatcher&) = delete;
ErrorDispatcher& operator = (ErrorDispatcher&&) = delete;
static ErrorDispatcher instance_;
std::function<void(std::string)> error_callback_func = nullptr;
};
}
NOTE: above I have inline implementation details in the public header to make this post shorter but they will be moved to a .cpp and won't be part of the public header
errordispatcher.cpp:
#include "errordispatcher.h"
namespace WE
{
ErrorDispatcher ErrorDispatcher::instance_;
}
apitest.h
namespace WE
{
void dllFunctionThatMightGiveError();
}
apitest.cpp
#include "errordispatcher.h"
#include "apitest.h"
namespace WE
{
void dllFunctionThatMightGiveError()
{
// Some error happens in dll so call user function and give a message to the user!
ErrorDispatcher::getInstance().dispatchError("Error in DLL!");
}
}
main.cpp (USER APP)
#include "errordispatcher.h"
#include "apitest.h"
#include <iostream>
#include <string>
void error_callback(std::string message)
{
std::cout << message << "\n";
}
int main(void)
{
WE::ErrorDispatcher::getInstance().setErrorCallback(error_callback);
WE::ErrorDispatcher::getInstance().dispatchError("Error in APP!");
WE::dllFunctionThatMightGiveError();
return 0;
}
Output is:
Error in APP!
Error in DLL!

undefined reference to 'typeinfo for Thread'

I had write this code but compiler throw me an error and have no idea why :S
So I was wondering that you can help me:
This is an abstract class for an easy thread implementation:
#ifndef THREAD_H
#define THREAD_H
#include <pthread.h>
class Thread {
public:
void start();
inline pthread_t getThread() const{
return _thread;
}
private:
pthread_t _thread;
inline static void* callRun(void* pObject){
((Thread*)pObject)->run();
return (void*)0;
}
protected:
virtual void* run();
};
#endif /* THREAD_H */
The source code is:
#include "Thread.h"
void Thread::start(){
pthread_attr_t attrib;
pthread_attr_init(&attrib);
pthread_attr_setdetachstate(&attrib, PTHREAD_CREATE_JOINABLE);
pthread_create(&_thread, &attrib, callRun, (void*)this);
pthread_attr_destroy(&attrib);
}
And the class PlayersManager inherit from Thread
#ifndef PLAYERMANAGER_H
#define PLAYERMANAGER_H
#include "Thread.h"
class PlayersManager : public Thread {
private:
void movePlayers();
void checkPlayers();
void* run();
};
#endif /* PLAYERMANAGER_H */
but I get the next compile error:
build/Debug/GNU-Linux-x86/PlayersManager.o:(.rodata._ZTI14PlayersManager[_ZTI14PlayersManager]+0x8): undefined reference to `typeinfo for Thread'
Any idea of what is happening? Thanks.

How to propagate keyPressEvent on different qt QMainWindow

I have 2 different QMainWindow, the first is the parent of the second. I want press some keys in the children windows and propagate the event in the parent. I create for everyone the function void keyPressEvent(QKeyEvent* event); but when i press key on the children the event is not propagate to the parent. Why?
This is the code...
//Parent class.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QKeyEvent>
#include "test.h"
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
void keyPressEvent(QKeyEvent* event);
private:
Ui::MainWindow *ui;
test *form;
private slots:
void on_pushButton_clicked();
};
#endif // MAINWINDOW_H
//Parent class.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
form = new test(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::keyPressEvent(QKeyEvent* event)
{
qDebug() << event->text();
}
void MainWindow::on_pushButton_clicked()
{
form->show();
}
//Children class.h
#ifndef TEST_H
#define TEST_H
#include <QMainWindow>
#include <QKeyEvent>
namespace Ui {
class test;
}
class test : public QMainWindow
{
Q_OBJECT
public:
explicit test(QWidget *parent = 0);
~test();
protected:
void keyPressEvent(QKeyEvent* event);
private:
Ui::test *ui;
};
#endif // TEST_H
//Children class.cpp
#include "test.h"
#include "ui_test.h"
test::test(QWidget *parent) : QMainWindow(parent), ui(new Ui::test)
{
ui->setupUi(this);
}
test::~test()
{
delete ui;
}
void test::keyPressEvent(QKeyEvent* event)
{
qDebug() << event->text();
event->ignore();
}
A QMainWindow is a top-level window and that is usually where event propagation ends. I'm not entirely clear what may be the rule though when a top-level window is parented. By your results, I'll have to assume that it stands.
In any case, you should be able to get the event by defining a filter method in your MainWindow class and installing it on test class. Refer to this documentation.
You also have the option of overriding the event() method of QApplication.

Resources