Interdependent Classes

Pages: 123
Why would basic_entity have a move method at all? You'd only ever want to move mobile_entity objects, yes?
Well, yes, but I’m trying to anticipate something attempting to move an immobile object by giving it the move function, but not moving it. Maybe a better primitive name is attempt_move()? Idk. The problem is ...Hum... actually Idk your right I think.. I guess... ehhh... idk. The problem is I’m gonna have this event system that’s like passing messages around with the handlers so it’d be like

fire( new Event("move entity"," id=XXX x= 3 y= 10 ") );


and then a handler receives that and finds the Entity whose id is XXX, (which to them is just a basic_entity pointer) and moves it right three and forward 10. With XXX->move(3,10);

This is of course way over convoluted, and I think the Events were supposed to be for something else, but I don’t remember what or why now which makes me sad... :( It’s something about reactions I think?

Edit: anyways. Point is: the move call will be called regardless, so I have to at least implement it or I’ll have an error on my hands.
Last edited on
Fair enough. If you're managing all your entities in one big pool, then it might be necessary.

This might be a good use of the final keyword identifier. If the move() method on immobile_entity is final, then nothing that inherits it can override the method to make an immobile object mobile.
Last edited on
How does that work? Can you show me some syntax?
Sorry, I haven't read the whole thread, but
This might be a good use of the final keyword identifier. If the move() method on immobile_entity is final, then nothing that inherits it can override the method to make an immobile object mobile.
If it's desirable for movable and unmovable objects to have a type in common then the solution is either
1
2
3
4
5
6
7
8
class Base{};

class Movable : public Base{
public:
    virtual void move() = 0;
};

class Unmovable : public Base{};

Or, in interface-type design:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Base{};

class Movable{
public:
    virtual void move() = 0;
};

class Thing1 : public Base{};

class Thing2 : public Base, public Movable{
public:
    void move() override;
};

class Thing3 : public Base{};
Last edited on
All that aside, the circular dependency of the OP code snippet is not a problem syntactically:

Player.h
1
2
3
4
5
6
7
class Potion;

class Player {
  // ...
  void drink(Potion p);
  // ...
};


Potion.h
1
2
3
4
5
6
7
class Player;

class Potion {
  // ...
  void operator() (Player* p);
  // ...
};


Player.cpp
1
2
3
4
5
6
7
#include "Player.h"
#include "Potion.h"

void Player::drink(Potion p)
{
    p( this );
}


Potion.cpp
1
2
3
4
5
6
7
8
#include "Potion.h"
#include "Player.h"

void Potion::operator() (Player* p)
{
    p.damage(34,"fire");
    p.setArmor(p.getArmor() + 34);
}
@helios, ehh well ya missed one thing: they both have to have the move() function, whether necessary or not. This is because move will be called on them regardless of whether or not it is movable.


@keskiverto, that’s exactly what I was looking for, thanks!
1
2
3
4
5
6
7
8
class Base{};

class Movable : public Base{
public:
    virtual void move() = 0;
};

class Unmovable : public Base{};

@Helios, I think the Unmovable class might not be needed. Movable classes can inherit form Movable,
all unmovable classes can inherit from Base.
@helios, ehh well ya missed one thing: they both have to have the move() function, whether necessary or not. This is because move will be called on them regardless of whether or not it is movable.
A class should not have a function it's not capable of performing. If you need to move() all the objects in a container then that container should be of Movables, not of some superclass that may or may not be able to move().
To give the typical example, you wouldn't make Cat a subclass of Dog with members bark() and meow() and have bark() do nothing. That's not how OOD works.

@Helios, I think the Unmovable class might not be needed. Movable classes can inherit form Movable,
all unmovable classes can inherit from Base.
I wanted to emphasize that a Base is an object whose movability is unknown, while a Movable can definitely move and an Unmovable can definitely not move. The immovable objects are all of a type that is unrelated to Movable.
Last edited on
Ahh don’t you just love it when you get fake mindflayers instead of programming concepts? https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=10&ved=2ahUKEwixkPXK0q7pAhUNl3IEHft1D4oQFjAJegQIBxAB&url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FOod&usg=AOvVaw1yE4i9BxRnFxuRR5gIpL1w

Anyways. What is OOD? did you mean OOP? Oh ObjectOrientedDesign. I see lol.

Hrrnghhh ok. But how do I handle something trying to move an immovable object then?
Last edited on
You can't move an immovable object, obviously. If you have an object that you don't know if it's movable or not and you want to attempt to move it, then you need to check first, either with dynamic_cast() or by some other method, then static_cast and then make the call.

Again, I assume you have some set of objects of variable movability and you're trying to move all of them. To me this is a strange situation.
What exactly are you trying to accomplish? Under what circumstances would you need to move an object that's of a type that's fundamentally incapable of moving?
Ye I have an object that I don’t know if I can move it. I never really got that far into casting, can you tell me how that would work? Maybe provide an example?

No circumstances. The only thing that the empty move function is for is because I call the function blindly, without knowing if it can move or not. I’m just trying to prevent an error. 🤷‍♂️
You have one object? Can you show me the context where you're trying to move it?
Gah sry that’s not what I mean. Hum.. ok.. so...


I have a player (just one)
The player attempts to move a Wall.
in the code it’d be something like
entities[x]->move(3,0);
Where entities is a vector of Entity* s
Is the player able to do anything else with an entity? Where do the parameters for move() come from?
There is another way to think about moveability:
* Everything is movable. Some things just move less than others.

This, of cource can lead to unexpected results:
* Player tosses pebble for 2 meters, but underestimates strenght. Pebble moves 5 meters.
* Player tosses Wall for 2 meters. Wall moves 0. Bonus side-effect: player dies.

In other words, this method does not allow you to assume that object has moved 2m after the toss(2m) call.
In fact, everything is tossable, which does different things depending on the thing being tossed.
Indeed, that's the more correct way to represent this situation. The code that Player executes should reflect the actions the player takes, not the effects of said actions. The effects should be determined by the object.
@helios it comes from entity

@keskiverto this is what I am making, yeah like that!


@helios hm ahh ok. Hm. Ok I’ll think of something then, this’ll be a little harder, but it gets exactly at what I was trying to do. Thank you! :)
How does that work? Can you show me some syntax?

Oh come on. You're as capable as typing "C++ final" into Google as I am.
Oops right lol thanks.
Pages: 123