How can I reach my subclass? C++ - c++

In the following code I can't reach my subclass. I have to have my subclass underneath the superclass to inherit it, but the superclass won't know what to point to unless the subclass is defined before it.
class ParticleSystem
{
Particle *ptr_to_particles;
void update()
{ // Loop through number of particles
// and call their update method.
ptr_to_particles[i].update();
}
}
class Particle : public ParticleSystem //Inherits ParticleSystem
{
void update();
}
Or if anyone can offer suggestions about how to do it differently, I welcome it. Thanks.

I think you should reconsider your design. A ParticleSystem should have a number of Particle (e.g. std::vector<Particle>). It doesn't seem correct for a Particle to be a type of ParticleSystem. Something like this
class Particle
{
public:
void update();
};
class ParticleSystem
{
public:
void update()
{
for (auto particle : _particles)
{
particle->update();
}
}
private:
std::vector<Particle*> _particles;
};

You should probably change your design. A Particle is not a logical subtype of a ParticleSystem. A ParticleSystem is just a composition of Particles, not a supertype of Particle.
class Particle
{
void update();
};
class ParticleSystem
{
Particle* particles;
void update()
{
// forall i
particle[i].update();
}
};

Related

Create a temporary interface into an object?

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 ...

Calling a function of another class from another class

I am working on a project where there are two player objects and one game object.
The two player objects need to access the game object's function display(), but i have no idea how this could be done.
Below is a snippet highlighting the core issue:
class Game
{
public:
Game() {}
display() {...}
...
};
class Player
{
public:
Player() {}
void input()
{
...
// display();
...
}
};
Please suggest a way to solve this problem. if you find fundamental issue with this design pattern, feel free to correct that!
Why not?
void input()
{
game.Display();
}
but probably, you need to pass a Player object to it. Thus, change it this way:
class Player; // FORWARD declaration
class Game
{
public:
Game() {}
void display(Player& player); // Implement elsewhere not here.
// Another way
void display(Player* player = NULL); // Implement elsewhere not here.
...
};
...
void input()
{
game.Display(*this);
game.Display(this); // another way
}

Component based architecture c++

I'm having trouble figuring out a way to make a component based engine architecture in c++. But i cant figure out a way to combine a vector of components with a class that derives from component.
I want to override components virtual function. But the only way i can make it call the overrided function is to make the component-derived class a pointer, but i want every gameobject to contain its own components in a vector and not outside the class as a pointer.
I tried to remove as much unnecessary code as possible.
My structure:
//GameObject class, contains components and other objects
class GameObject
{
public:
GameObject(){}
~GameObject(){}
void AddChild(GameObject child)
{
children.push_back(child);
}
void AddComponent(Component component)
{
components.push_back(component);
}
void Input(){}
void Update(){}
void Render()
{
for(unsigned int i = 0; i < components.size(); i++)
components[i].Render();
}
private:
std::vector<GameObject> children;
std::vector<Component> components;
};
//base class component
class Component
{
public:
Component(){}
~Component(){}
virtual void Input(){}
virtual void Update(){}
virtual void Render(){ cout << "Component -> Render()" << endl; }
};
class MeshRenderer : public Component
{
public:
MeshRenderer(Mesh _mesh, Material _material)
{
mesh = _mesh;
material = _material
}
~MeshRenderer(){}
//override components virtual Render()
void Render(Transform transform)
{
mesh.Render(material);
cout << "MeshRenderer -> Render()" << endl;
}
private:
Mesh mesh;
Material material;
};
GameObject* root = new GameObject();
MeshRenderer meshRenderer(mesh, material);
root->AddComponent(meshRenderer);
//GameLoop
while(!quit)
{
root->Render();
}
It would be the best if you could use unique_ptr:
void AddComponent(std::unique_ptr<Component> component) {
components.push_back(std::move(component));
}
std::vector<std::unique_ptr<Component>> components;
Thus by calling AddComponent() you transfer ownership of the component to containing GameObject.
Looks like you want to pass your objects by reference, use
void AddComponent(Component& component);
to avoid any slicing.
For proper usage with std::vector<>'s and polymorphic inheritance, you'll need smart pointers, e.g. std::unique_ptr<Component> to preserve ownership, or std::shared_ptr<Component> for shared ownership (raw pointers as Component* might work as well, but are far harder to manage correctly).
void AddComponent(std::unique_ptr<Component> componentPtr); // Unique ownership
or
void AddComponent(std::shared_ptr<Component> componentPtr); // Shared ownership
and accordingly
std::vector<std::unique_ptr<Component>> components;
or
std::vector<std::shared_ptr<Component>> components;
It depends on your actual use cases if these Component instances should be uniquely owned by their aggregating parent GameObject class, or not.
To use std::shared<> pointers, that could expire outside their usages scope you may consider using std::weak_ptr<>.
As mentioned, it totally depends on your use cases, and how you want these aggregated components being accessible from outside of the GameObject class.

vector of pointers to abstract class

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().

Refactoring code for drawing game components

How can I refractor the following, to move my drawing functions from the h-file into a GraphicsManager class?
//drawingFunctions.h
void drawTexturedQuad( Texture texture, Vector2 pos, Vector2 dim) {
// bind texture...
glBegin(...); // draw
//...
glEnd(...);
}
//class file
#include "drawingFunctions.h"
class Player {
void drawPlayer(){ drawTexturedQuad( texture, pos, dim) }
};
class Enemy {
void drawEnemy(){ drawTexturedQuad( texture, pos, dim) }
};
class Item {
void drawItem(){ drawTexturedQuad( texture, pos, dim) }
};
// and so on for the other components
//gameloop file
// instantiate components objects
while (true) {
// input, logic
Player.drawPlayer();
Enemy.drawEnemy();
Item.drawItem();
// and so on
}
(The code is obviously simplified, I am just asking about the drawing here)
Should I...
pass a pointer to the GraphicsManager to every call of drawPlayer, drawEnemy etc from within the gameloop
have Player, Enemy etc have a pointer to GraphicsManger as a data member
have Player, Enemy etc extend a drawableGameComponent class that has a pointer to GraphicsManager as a data member
something else?
That sounds like a perfect use case for inheritance:
class Drawable
{
public:
void draw()
{
// gl stuff
}
protected:
Texture _texture;
Vector2 _pos;
Vector2 _dim;
};
class Player : Drawable
{
public:
// should modify _texture _pos and _dim somewhere.
};
// same thing for the other objects.
I would pass a renderer to the model, and ask it to draw itself.
class Player
{
public:
void draw(Renderer& renderer);
};
class Enemy
{
public:
void draw(Renderer& renderer);
};
Note you don't have to name the function drawPlayer or drawEnemy, because you already know that it's a Player or an Enemy by the class type. This uniform calling convention is perfect for extracting into a common interface:
class Model
{
public:
virtual void draw(Renderer& renderer) = 0;
virtual ~Model() {}
};
Then you can have each of your models inherit from Model, and each implement draw.
As I mentioned in a comment on #J.N.'s answer you can also have Renderer be an abstract class. For example I worked on a project which used OpenGL, GDI+, and also needed to create printouts of schematics.
class Renderer
{
public:
virtual render(const Triangle& triangle, const Texture& texture) = 0;
virtual ~Renderer() {}
};
I would go for the first possibility: passing the pointer to the GraphicsManager in the call. Eventhough it seems a bit overkill, the knowledge of which GraphicsManager is used is maintained on higher level and can be modified easier later on.
Having said this, I would still inherit from a Drawable interface and put the items that need to be drawn in a container, so you can just iterate through it to display the items via a virtual drawItem() function.
Like so (C++03, not tested):
std::vector<Drawable*> Items;
Items.push_back(&player);
Items.push_back(&enemy);
...
for (std::vector<Drawable*>::iterator it = Items.begin(); it != Items.end(): ++it)
{
(*it)->drawItem(&graphMgr);
}