I'm trying to implement the observer pattern in C++. What I attempting to do is to declare an observer interface with a single pure virtual method: notify(), and then let the the observers implement/derive that interface. Additionally, I want to keep a vector of pointers to all the observer classes in the observed class, so that I can call notify() on each of them. Sadly I'm having some trouble with the vector of pointers.
This is the observer interface:
class LocationEstimateObserver {
public:
virtual void notify() = 0;
};
I have two different classes implementing this interface. Hence, both implement the notify() method.
Here my observed class:
class Simulator {
public:
Simulator();
virtual ~Simulator();
void registerListener(LocationEstimateObserver& observer){observers_.push_back(&observer); };
void notifyObservers();
private:
std::vector<LocationEstimateObserver*> observers_;
};
And the observer class (implements the observer interface):
void InMapsEngine::startSimulation() {
Simulator sim();
sim.registerListener(*this);
}
And the Simulator.cpp file:
void Simulator::notifyObservers() {
for (unsigned int i = 0; i < observers_.size(); i++) {
observers_.at(i)->notify();
}
}
Now when I run the above code I get a segmentation fault. Could anyone of you point out what what I am doing wrong? I'm very new to C++.
EDIT: I just made a bizarre discovery: when I call observers_.size() it returns a very odd negative number, so the for loop fails. There lies the problem.
Why instead of adding instances of subclasses of LocationEstimateObserver, don't you have a vector of functions that will be notified when something will occur?:
Something like:
class Simulator {
public:
Simulator();
virtual ~Simulator();
void registerListener(const function<void()>& observer ) {observers_.push_back(observer); };
void notifyObservers();
private:
std::vector<function<void()>> observers_;
};
void observer1()
{
}
int main()
{
Simulator sim;
sim.registerListener(observer1);
}
And the Simulator.cpp file:
void Simulator::notifyObservers() {
for (auto& observer : observers_)
observer();
}
You keep a vector of pointers to objects that could have been deleted right after being registered. Make sure they are still there when you call Simulator::notifyObservers().
Related
I got an object tree. In the object tree I store SceneNodes. A SceneNode is usually the base class for other classes.
I want to implement different behavior for the objects that represent the SceneNodes.
The correct Pattern for this problem should be the visitor pattern. I want to iterate over the SceneNodes and want to call different functions based on the objects stored behind the SceneNodes.
But I not only want to allow one object in the object tree to be one component of the visitor pattern but to share functionality.
For example: I have a BaseObject. I can update this BaseObject (e.g. to a new position) and I can draw a BaseObject (OpenGL stuff).
But I also have a Camera object. The camera object can be updated but not drawn.
Here is the implementation of the Visitor Stuff:
class Visitor
{
public:
virtual void VisitUpdate(ComponentUpdate* element) = 0;
virtual void VisitDraw(ComponentDraw* element) = 0;
virtual void VisitOverlay(ComponentOverlay* element) = 0;
};
Visitor Component:
class Component
{
public:
virtual ~Component() { }
virtual void accept(Visitor* visitor) = 0;
};
Concrete Component:
class ComponentUpdate : public Component
{
public:
void accept(Visitor* visitor) override {
visitor->VisitUpdate(this);
}
virtual void update() = 0;
};
class ComponentDraw : public Component
{
public:
void accept(Visitor* visitor) override {
visitor->VisitDraw(this);
}
virtual void draw() = 0;
};
And finally a concrete visitor:
class SceneNodeVisitor : public Visitor
{
void VisitUpdate(ComponentUpdate* element) override {
element->update();
}
void VisitDraw(ComponentDraw* element) override {
element->draw();
}
};
Now I'd like to do something like this:
class Camera : public ComponentUpdate
{
void update() override { std::cout << "Camnera update" << std::endl; }
};
class ObjectBase : public ComponentDraw, public ComponentUpdate
{
void update() override { std::cout << "ObjectBase update" << std::endl; }
void draw() override { std::cout << "ObjectBase draw" << std::endl; }
};
Ok, so far so good. The problem I have now is that the compiler says "base class is ambiguous". I think this is not correct because ObjectBase is ambiguous because it has two different accept() functions, am I right?
Is there a way to use the visitor pattern so that I can freely anoint the classes with the functionality I need for them?
Here the main function:
int main() {
ObjectBase ob;
Camera cam;
SceneNodeVisitor visitor;
std::vector<Component*> components;
components.push_back(new Camera);
components.push_back(new ObjectBase);
components[0]->accept(&visitor);
components[1]->accept(&visitor);
}
Strange is that I can create the ObjectBase on the stack. I only get the error if I try to create the object on the heap (via new).
Pastebin is down at the moment, I can give you this example code as soon as it's up again.
Okay, I'm not entirely sure, but I think you should separate out some of the concepts you're doing.
As soon as you inherit from two classes that both inherit from the same base class, you need to start looking at virtual inheritance. That might solve your problem. But the path from ObjectBase to Component is either through ComponentDraw or ComponentUpdate. In effect, you probably have two copies of Component because you're not using virtual inheritance.
I would strongly consider using the concept of interfaces. While C++ technically doesn't have them, you can make them, anyway.
And look at virtual inheritance.
In Java you can create an object whilst at the same time providing (or overloading) abstract functions within the object, thus:
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Whatever in here
}
};
I really like that way of doing it, and was wondering if there was some similar construct in C++.
Basically I want a base class with a couple of PV functions declared in it (amongst other stuff), and the user to create an instance of that class whilst at the same time providing the body of the PV functions.
I know I could create child classes, but that seems a little clunky for what I need, where each child class would be unique and only be used to make one instance each.
I have thought about providing lamdas to the constructor and using those instead of actual member functions, but that really seems messy and hard for a novice user to get their head around - not to mention that it would be too rigid (I'd also like to be able to override some non-pure virtual functions optionally).
So is child classes the only way to go, or is there some lesser-known construct in some newer C++ standard that I don't know about that could do what I want?
To expand a little - the idea is to have a class like:
class Thread {
// other stuff
public:
virtual void setup() = 0;
virtual void loop() = 0;
// other functions, some virtual but not pure
};
Thread threadOne {
void setup() {
// Init code for this thread
}
void loop() {
// Run code for this thread
}
};
Thread threadTwo {
void setup() {
// Init code for this thread
}
void loop() {
// Run code for this thread
}
};
Obviously not that syntax, but it gives you an idea of how I'd like to use the class.
It's intended to be run on an embedded system with a slimmed-down C++ implementation (it's g++ but without the full STL). End users aren't the brightest bunch, so it has to be kept as simple to understand as possible.
Anonymous child classes are the closest to what I'd like (though still not perfect). I can use CPP macros to help abstract some of the class implementation syntactic sugar which would help.
Here's a compilable construct I have come up with. Is there anything "wrong" with this approach given the constraints above?
#define THREAD(NAME, CONTENT) class : public Thread {\
public:\
CONTENT\
} NAME;
class Thread {
private:
uint32_t stack[256]; // 1kB stack
volatile bool _running;
public:
virtual void setup() = 0;
virtual void loop() = 0;
void start();
void stop();
uint8_t state();
static void spawn(Thread *thr);
void threadRunner();
};
void Thread::spawn(Thread *thread) {
thread->threadRunner();
}
void Thread::start() {
Thread::spawn(this);
}
void Thread::threadRunner() {
_running = true;
setup();
while (_running) {
loop();
}
}
void Thread::stop() {
_running = false;
}
uint8_t Thread::state() {
return 0;
}
THREAD(myThread,
void setup() override {
}
void loop() override {
}
)
void setup() {
myThread.start();
}
void loop() {
}
Obviously it doesn't actually do anything yet - the whole of the threading back-end is a separate issue, and will be ported over from some existing code I wrote a few years back. I am mainly interested in simplifying the interface for the end user.
There is multiple possibilities, but I'd stick with something simple and versatile: callbacks and lambdas instead of virtual function and inheritance.
class ActionListener
{
std::function<void(int)> _action_performed;
public:
template<class CB>
ActionListener(CB cb) : _action_performed(cb) {}
void click() { _action_performed(0); }
};
int main()
{
ActionListener al([](int n) { std::cout << "Action Performed #" << n << "\n"; });
al.click(); // prints "Action Performed #0"
}
live demo
I'd also like to be able to override some non-pure virtual functions optionally
Which, semantically speaking, means providing a default behavior. This is possible:
ActionListener(CB cb) : _action_performed(cb) {} // construct an AL with the given callback
ActionListener() : _action_performed(default_action_performed) {} // construct an AL with a default callback
void default_action_performed(int n) { /*...*/ }
well, as you already mentioned, one way would be child classes.
another way would be providing some std::functions (or lambdas), either in the constructor or have some set functions.
store the function as a member and call this once your "virtual" member function is called: If you want it optional:
class MyBase
{
public:
MyBase();
void SetFunc(const std::function<int()>& myFun)
{
m_myFun = myFun;
}
int MyVirtFunc()
{
if(m_myFun)
{
return m_myFun();
}
else
{
return 42;
}
}
private:
std::function<int()> m_myFun;
}
if you want the functions given mandatory, put them in the constructor:
class MyBase
{
public:
MyBase(const std::function<int()>& myFun)
: m_myFun(myFun) {}
int MyVirtFun() { return m_myFun(); }
private:
const std::function<int()> m_myFun;
}
I have an object "World obj;" that has a normal interface of methods for it's typical funcitonality, but I want to have an additional interface of methods specifically for initializing that should only be visible when I specifically need them.
An example might be like this:
class World{
public:
void draw();
void update();
void normalStuff();
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
Is there a way to relatively hide addATree(); etc in a way that makes sense? Ideally the mechanism for revealing those methods would also put the object into a ready state for them, or at least fault if it's not possible.
Different approaches would be possible:
Don't change the code, just change the spec
No need to change the code. Change the API specification and if the caller throws garbage in he gets garbage out.
Make the functions check if they are allowed
Always safe.
class World{
public:
...
void addAClown() {
if(not allowed)
throw error or crash or output error message or just return;
else {
do the work;
}
}
private:
int m_data;
};
Write a function that only exposes the Interface if allowed
You can't protect against someone getting the interface early and use it longer than allowed.
You could extract the interface functions into a separate class.
class WorldInterfaceToProtect {
public:
void addATree() = 0; // this should not be ordinarily available or visible,
void addACar() = 0; // calling this might break the object
void addAClown() = 0;// if it's not in a ready state for it
};
then the main class can protect these functions.
class World : protected WorldInterfaceToProtect {
public:
void draw();
void update();
void normalStuff();
protected:
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
You then need to add a function that exposes the interface.
class World ... {
public:
WorldInterfaceToProtect *GetInterface() { return allowed_cond ? this : nullptr; }
...
}
Separate the class itself and the builder
This only helps if the functions to be called are only allowed during construction and not later. Depending on the design of the builder you can get a good protection.
class World{
friend class WorldBuilder;
public:
void draw();
void update();
void normalStuff();
protected:
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
class WorldBuilder {
static World *Build(...);
}
Perhaps split the world into more composable parts:
struct WorldInterface
{
virtual void draw() = 0;
virtual void update() = 0;
virtual void normalStuff() = 0;
};
class World : public WorldInterface
{
public:
void draw() override { /* actual drawing here */};
void update() override {};
void normalStuff() override {};
private:
int m_data;
};
class TreeWorld : public WorldInterface
{
public:
// takes a reference to the actual world engine and defers work to
// that
TreeWorld(World& worldEngine) : worldEngine_(worldEngine) {}
void draw() override { worldEngine_.get().draw(); };
void update() override { worldEngine_.get().update(); };
void normalStuff() override { worldEngine_.get().normalStuff(); };
void addATree() {
//do tree/world interaction here
}
private:
std::reference_wrapper<World> worldEngine_;
};
class CarWorld : public WorldInterface
{
public:
// takes a reference to the actual world engine and defers work to
// that
CarWorld(World& worldEngine) : worldEngine_(worldEngine) {}
void draw() override { worldEngine_.get().draw(); };
void update() override { worldEngine_.get().update(); };
void normalStuff() override { worldEngine_.get().normalStuff(); };
void addACar() {
//do car/world interaction here
}
private:
std::reference_wrapper<World> worldEngine_;
};
extern void play_tree_game(TreeWorld world);
extern void play_car_game(CarWorld world);
int main()
{
World worldEngine;
// initialise engine here
// play tree-phase of game
play_tree_game(TreeWorld(worldEngine));
// play car phase of game
play_car_game(CarWorld(worldEngine));
}
Good answers all around, I'll just add this because it was missing(?)
class World{
public:
void draw();
void update();
void normalStuff();
private:
int m_data;
};
class BuildableWorld : public World
{
public:
void addATree();
void addACar();
void addAClown();
};
Use the BuildableWorld at initialization phase and then just give a pointer to the base class type for others to use.
Sure, you need some way to give the "built" data for the base class to access, but that was not the issue here, right?
an alternative approach that has not been mentioned so far, may be to let addX() functions take parameters whose existence implies that World is in a valid state. Say, if you cannot add trees to a world without water, let World return an (optional) water object to pass to addTree ... in other words, you need to properly formalize World invariants:
class World{
public:
void normalStuff();
auto getAvaliableWaterBuckets() -> optional<WaterBuckets>;
auto getAvaliableSoil() -> optional<SoilPack>;
//...
void addATree( WaterBuckets&&, SoilPack&& );
//...
};
// in the meanwhile, in user land:
if( auto water = world->getAvaliableWaterBuckets() )
if( auto soil = world->getAvaliableSoil() )
world->addTree( std::move(*water), std::move(*soil) );
else
world->recycleWater( std::move(*water) );
the benefit of this approach is that the user is not forced to think about world state validity ( an error prone task ), he just thinks about what he needs in order to add a tree ( simpler, hard to use incorrectly ). Moreover, this scales well because addX() functions can share different objects ( addFlowers needs water, ... ) enabling the correct management of a possibly complex internal world state.
Of course, IMHO, if you need to use addX() strictly on world construction only ( and you don't plan to add trees later ), then the factory approach already mentioned in the comments seems the way to go ...
I'm new to C++ and i'm having a hard time figuring out what's wrong with my virtual functions. So, here's what i have:
GEntity.h
class GEntity
{
public:
//...
virtual void tick(void);
virtual void render(void);
//...
};
GEntity.cpp
//...
void GEntity::tick(void){}
void GEntity::render(void){}
//...
GLiving.h
class GLiving : public GEntity
{
public:
//...
virtual void tick(void);
virtual void render(void);
//...
};
GLiving.cpp
//...
void GEntity::tick(void){}
void GEntity::render(void){}
//...
Then i have other classes that derive from GLiving (Player, Enemy) which implement their own versions of this two methods:
Player.h
class Player : public GLiving
{
public:
//...
void tick(void);
void render(void);
//...
};
Player.cpp
//...
void GEntity::tick(void)
{
//Here there's some actual code that updates the player
}
void GEntity::render(void)
{
//Here there's some actual code that renders the player
}
//...
Now, if i declare an object of class Player, and call the render/tick method, everything goes well, but i am in a situation in which i add my player to an arraylist (a struct i created) of GEntity, and then, when i get it back, i get it as a GEntity, and i need to call the render/tick methods without knowing it's derived class...
I've tried with the code above, but i get an access violation in the line where i call either the render or tick method, on the extracted GEntity...
...is what i want even possible to achieve?
(sorry if my english is not so good, but i'm italian)
If you have an array of GEntity then, each time you "add" a derived type, the equivalent of this happens:
GEntity g;
Player p;
g = p; // object slicing, you assigned a Player to a GEntity object.
g.render(); // GEntity::render() gets called
On the other hand, you can use a pointer to a base class to access a derived method:
GEntity* g;
Player p;
g = &p;
g->render(); // calls Player::render()
So a way to deal with polymorphism in containers is to have arrays/containers of (preferably smart) pointers to the base class. This example uses raw pointers for simplicity, but you should use smart pointers in real code:
std::vector<CEntity*> entities;
entities.push_back(new Player);
entities.push_back(new GLiving);
// some c++11
for ( auto e : entities) {
e->render();
}
I am having a problem with the following code, the overriden virtual functions are not executing. Not sure i'm doing wrong here probably a silly mistake. Anyway this is a game project and I have an array of objects which looks like this (the core::array is an irrlicht array, similar to the vector array)
core::array<GameObject> gameTargets;
This is the GameObject and Zombie definition
class GameObject {
protected:
scene::ISceneNode* node;
public:
int ID;
int hitpoints;
GameObject() {
...
};
void setNode(scene::ISceneNode* inode) {
...
}
virtual void shot(int dmg) {
... [BREAKPOINT HERE]
}
scene::ISceneNode* getNode() {
return node;
}
};
class Zombie : public GameObject {
public:
static const enum Animation {
ZOMBIE_WALK,
ZOMBIE_HURT,
ZOMBIE_DIE,
ZOMBIE_TWITCH,
ZOMBIE_ATTACK,
ZOMBIE_IDLE
};
//We only want to accepted animated mesh nodes for this object
Zombie(int hp, scene::IAnimatedMeshSceneNode* inode) {
...
}
//Override the shot function
void shot(int dmg) {
... [BREAKPOINT HERE]
}
//Animate the zombie
void setAnimation(Animation anim) {
...
}
};
The member functions of the derived classes is never called, I am creating the objects like this
Zombie target(hp, (scene::IAnimatedMeshSceneNode*)node);
and calling the virtual function like this
for(int i = 0; (u32)i<level->gameTargets.size(); i++) {
if(selectedNode == level->gameTargets[i].getNode()) {
level->gameTargets[i].shot(b->damage);
}
}
where b is a pointer to a bullet with a int variable damage and gameTargets contains GameObject
I suspect that you're experiencing slicing because the gameTargets array contains values. I can't tell for sure because I don't know how the core::array template works. See What is object slicing? for a discussion about what slicing is.
To fix this problem, store either raw pointers as in
core::array<GameObject *> gameTargets;
Or use some sort of reference-counted pointer like
core::array<std::shared_ptr<GameObject>> gameTargets; // only available in C++11
array<GameObject> is a container of objects, not a container of pointers. Every object you add to it will be a GameObject and not one of the derived classes (if you add a derived class object, then it'll be "sliced").
Without knowing exactly what your core::array does, I suspect what you really intended to create is an array of std::unique_ptr<GameObject> (smart pointers) along the lines of
core::array< std::unique_ptr<GameObject> > gameTargets;
std::unique_ptr<GameObject> my_zombie(new Zombie);
gameTargets.push_back( my_zombie );
a quick solution would be to make those parent functions as pure virtual functions, as in:
virtual void shot(int dmg) { } = 0;
// edit
and use array of pointer as suggested by Frerich Raabe