Say I have the following classes:
class Airplane
{
virtual bool Fly(uint64_t destinationID)
{
//Do what an airplane does to be flown.
}
/*
* More function and data members.
*/
}
class SomeModel: public Airplane
{
virtual bool Fly(uint64_t destinationID);
{
//Do something that SomeModel specifically should do before it gets flying.
//Do exactly what Airplane::Fly does.
}
}
My question is how to implement SomeModel::Fly. One simple way is as follows:
virtual bool SomeModel::Fly(uint64_t destinationID)
{
//Do something that SomeModel specifically should do before it gets flying.
Airplane::Fly(destinationID);
}
Is there a nicer way of doing it? Or is there another reason for choosing another way. I know this is a general question but it's the first time I have to implement such a method so I want to make sure I'm not missing anything.
EDIT
I find it worth to emphasize that Airplane is not a general or abstract class, many Airplane in the company are just airplanes and appear as such without any inhritance, there is one specific model though that has some specific behavior.
This really depends on what you are trying to achieve. Your example is certainly valid and one solution to one type of problem (where a some setup or other variations are required early on).
Another variant on this theme is to use a virtual setup, and then a common "fly" method.
So:
class Airplane
{
bool Fly(uint64_t destinationID)
{
SetupForFlight();
// do actual flying stuff
...
...
}
virtual void SetupForFlight() { // do nothing for standard airplane }
}
class Boeing747: public Airplane
{
...
void SetupForFLight()
{
... do stuff that needs to be set up here.
}
...
}
There are benefits with both of these methods, and it will probably depend on what you are modelling which is better.
Of course, you could have a AfterLanding type function at the end of Fly as well.
Just out of curiousity, are there so many destinations that you need a 64-bit value for them - I've never really considered it, just curious.
Edit: I think what I'm describing is a "Template method pattern". I'm not great with names for these things, I just know how it's working....
Related
i'm creating particle system and i want to have possibility to choose what kind of object will be showing on the screen (like simply pixels, or circle shapes). I have one class in which all parameters are stored (ParticleSettings), but without those entities that stores points, or circle shapes, etc. I thought that i may create pure virtual class (ParticlesInterface) as a base class, and its derived classes like ParticlesVertex, or ParticlesCircles for storing those drawable objects. It is something like that:
class ParticlesInterface
{
protected:
std::vector<ParticleSettings> m_particleAttributes;
public:
ParticlesInterface(long int amount = 100, sf::Vector2f position = { 0.0,0.0 });
const std::vector<ParticleSettings>& getParticleAttributes() { return m_particleAttributes; }
...
}
and :
class ParticlesVertex : public ParticlesInterface
{
private:
std::vector<sf::Vertex> m_particleVertex;
public:
ParticlesVertex(long int amount = 100, sf::Vector2f position = { 0.0,0.0 });
std::vector<sf::Vertex>& getParticleVertex() { return m_particleVertex; }
...
}
So... I know that i do not have access to getParticleVertex() method by using polimorphism. And I really want to have that access. I want to ask if there is any better solution for that. I have really bad times with decide how to connect all that together. I mean i was thinking also about using template classes but i need it to be dynamic binding not static. I thought that this idea of polimorphism will be okay, but i'm really need to have access to that method in that option. Can you please help me how it should be done? I want to know what is the best approach here, and also if there is any good answer to that problem i have if i decide to make that this way that i show you above.
From the sounds of it, the ParticlesInterface abstract class doesn't just have a virtual getParticleVertex because that doesn't make sense in general, only for the specific type ParticlesVertex, or maybe a group of related types.
The recommended approach here is: Any time you need code that does different things depending on the actual concrete type, make those "different things" a virtual function in the interface.
So starting from:
void GraphicsDriver::drawUpdate(ParticlesInterface &particles) {
if (auto* vparticles = dynamic_cast<ParticlesVertex*>(&particles)) {
for (sf::Vertex v : vparticles->getParticleVertex()) {
draw_one_vertex(v, getCanvas());
}
} else if (auto* cparticles = dynamic_cast<ParticlesCircle*>(&particles)) {
for (CircleWidget& c : cparticles->getParticleCircles()) {
draw_one_circle(c, getCanvas());
}
}
// else ... ?
}
(CircleWidget is made up. I'm not familiar with sf, but that's not the point here.)
Since getParticleVertex doesn't make sense for every kind of ParticleInterface, any code that would use it from the interface will necessarily have some sort of if-like check, and a dynamic_cast to get the actual data. The drawUpdate above also isn't extensible if more types are ever needed. Even if there's a generic else which "should" handle everything else, the fact one type needed something custom hints that some other future type or a change to an existing type might want its own custom behavior at that point too. Instead, change from a thing code does with the interface to a thing the interface can be asked to do:
class ParticlesInterface {
// ...
public:
virtual void drawUpdate(CanvasWidget& canvas) = 0;
// ...
};
class ParticlesVertex {
// ...
void drawUpdate(CanvasWidget& canvas) override;
// ...
};
class ParticlesCircle {
// ...
void drawUpdate(CanvasWidget& canvas) override;
// ...
};
Now the particles classes are more "alive" - they actively do things, rather than just being acted on.
For another example, say you find ParticlesCircle, but not ParticlesVertex, needs to make some member data updates whenever the coordinates are changed. You could add a virtual void coordChangeCB() {} to ParticlesInterface and call it after each motion model tick or whenever. With the {} empty definition in the interface class, any class like ParticlesVertex that doesn't care about that callback doesn't need to override it.
Do try to keep the interface's virtual functions simple in intent, following the Single Responsibility Principle. If you can't write in a sentence or two what the purpose or expected behavior of the function is in general, it might be too complicated, and maybe it could more easily be thought of in smaller steps. Or if you find the virtual overrides in multiple classes have similar patterns, maybe some smaller pieces within those implementations could be meaningful virtual functions; and the larger function might or might not stay virtual, depending on whether what remains can be considered really universal for the interface.
(Programming best practices are advice, backed by good reasons, but not absolute laws: I'm not going to say "NEVER use dynamic_cast". Sometimes for various reasons it can make sense to break the rules.)
I'm trying to encapsulate existing functionality in a wide swathe of classes so it can be uniformly modified (e.g. mutexed, optimized, logged, etc.) For some reason, I've gotten it into my head that (multiple) private inheritance is the way to go, but I can't find what led me to that conclusion.
The question is: what is the name for what I am trying to do, and where I can see it done right?
What I think this isn't:
Decorator: All the descriptions I see for this pattern wrap a class to provide extra methods as viewed from the outside. I want to provide functionality to the inside (extract existing as well as add additional.)
Interface: This is close, because the functionality has a well-defined interface (and one I would like to mock for testing.) But again this pattern deals with the view from the outside.
I'm also open to alternatives, but the jackpot here is finding an article on it written by someone much smarter than me (a la Alexandrescu, Meyers, Sutter, etc.)
Example code:
// Original code, this stuff is all over
class SprinkledFunctionality
{
void doSomething()
{
...
int id = 42;
Db* pDb = Db::getDbInstance(); // This should be a reference or have a ptr check IRL
Thing* pThing = pDb->getAThing(id);
...
}
}
// The desired functionality has been extracted into a method, so that's good
class ExtractedFunctionality
{
void doSomething()
{
...
int id = 42;
Thing* pThing = getAThing(id);
...
}
protected:
Thing* getAThing(int id)
{
Db* pDb = Db::getDbInstance();
return pDb->getAThing(id);
}
}
// What I'm trying to do, or want to emulate
class InheritedFunctionality : private DbAccessor
{
void doSomething()
{
...
int id = 42;
Thing* pThing = getAThing(id);
...
}
}
// Now modifying this affects everyone who accesses the DB, which is even better
class DbAccessor
{
public:
Thing* getAThing(int id)
{
// Mutexing the DB access here would save a lot of effort and can't be forgotten
std::cout << "Getting thing #" << id << std::endl; // Logging is easier
Db* pDb = Db::getDbInstance(); // This can now be a ptr check in one place instead of 100+
return = pDb->getAThing(id);
}
}
One useful technique you might be overlooking is the non-virtual interface (NVI) as coined by Sutter in his writings about virtuality. It requires a slight inversion of the way you're looking at it, but is intended to address those precise concerns. It also tackles those concerns from within as opposed, to say, decorator which is about extending functionality non-intrusively from the outside.
class Foo
{
public:
void something()
{
// can add all the central code you want here for logging,
// mutex locking/unlocking, instrumentation, etc.
...
impl_something();
...
}
private:
virtual void impl_something() = 0;
};
The idea is to favor non-virtual functions for your public interfaces, but make them call virtual functions (with private or protected access) which are overridden elsewhere. This gives you both the extensibility you typically get with inheritance while retaining central control (something otherwise often lost).
Now Bar can derive from Foo and override impl_something to provide specific behavior. Yet you retain the central control in Foo to add whatever you like and affect all subclasses in the Foo hierarchy.
Initially Foo::something might not even do anything more than call Foo::impl_something, but the value here is the breathing room that provides in the future to add any central code you want -- something which can otherwise be very awkward if you're looking down at a codebase which has a boatload of dependencies directly to virtual functions. By depending on a public non-virtual function which depends on an overridden, non-public virtual function, we gain an intermediary site to which we can add all the central code we like.
Note that this can be overkill too. Everything can be overkill in SE, as a simple enough program might actually be the easiest to maintain if it just used global variables and a big main function. All of these techniques have trade-offs, but the pros begin to outweigh the cons with sufficient scale, complexity, changing requirements*.
* I noticed in one of your other questions that you wrote that the right tool for the job should have zero drawbacks, but everything tends to have drawbacks, everything is a trade-off. It's whether the pros outweigh the cons that ultimately determines whether it was a good design decision, and it's far from easy to realize all of this in foresight instead of hindsight.
As for your example:
// What I'm trying to do, or want to emulate
class InheritedFunctionality : private DbAccessor
{
void doSomething()
{
...
int id = 42;
Thing* pThing = getAThing(id);
...
}
}
... there is a significantly tighter coupling here than is necessary for this example. There might be more to it than you've shown which makes private inheritance a necessity, but otherwise composition would generally loosen the coupling considerably without much extra effort, like so:
class ComposedFunctionality
{
...
void doSomething()
{
...
int id = 42;
Thing* pThing = dbAccessor.getAThing(id);
...
}
...
private:
DbAccessor dbAccessor;
};
Basically what you're doing is decoupling the way you getAThing from the way you doSomething. Looks a lot like the Factory Method object-oriented design pattern. Have a look here:
Factory Method Pattern
I have a C background and am a newb on C++. I have a basic design question. I have a class (I'll call it "chef" b/c the problem I have seems very analogous to this, both in terms of complexity and issues) that basically works like this
class chef
{
public:
void prep();
void cook();
void plate();
private:
char name;
char dish_responsible_for;
int shift_working;
etc...
}
in pseudo code, this gets implemented along the lines of:
int main{
chef my_chef;
kitchen_class kitchen;
for (day=0; day < 365; day++)
{
kitchen.opens();
....
my_chef.prep();
my_chef.cook();
my_chef.plate();
....
kitchen.closes();
}
}
The chef class here seems to be a monster class, and has the potential of becoming one. chef also seems to violate the single responsibility principle, so instead we should have something like:
class employee
{
protected:
char name;
int shift_working;
}
class kitchen_worker : employee
{
protected:
dish_responsible_for;
}
class cook_food : kitchen_worker
{
public:
void cook();
etc...
}
class prep_food : kitchen_worker
{
public:
void prep();
etc...
}
and
class plater : kitchen_worker
{
public:
void plate();
}
etc...
I'm admittedly still struggling with how to implement it at run time so that, if for example plater (or "chef in his capacity as plater") decides to go home midway through dinner service, then the chef has to work a new shift.
This seems to be related to a broader question I have that if the same person invariably does the prepping, cooking and plating in this example, what is the real practical advantage of having this hierarchy of classes to model what a single chef does? I guess that runs into the "fear of adding classes" thing, but at the same time, right now or in the foreseeable future I don't think maintaining the chef class in its entirety is terribly cumbersome. I also think that it's in a very real sense easier for a naive reader of the code to see the three different methods in the chef object and move on.
I understand it might threaten to become unwieldy when/if we add methods like "cut_onions()", "cut_carrots()", etc..., perhaps each with their own data, but it seems those can be dealt with by having making the prep() function, say, more modular. Moreover, it seems that the SRP taken to its logical conclusion would create a class "onion_cutters" "carrot_cutters" etc... and I still have a hard time seeing the value of that, given that somehow the program has to make sure that the same employee cuts the onions and the carrots which helps with keeping the state variable the same across methods (e.g., if the employee cuts his finger cutting onions he is no longer eligible to cut carrots), whereas in the monster object chef class it seems that all that gets taken care of.
Of course, I understand that this then becomes less about having a meaningful "object oriented design", but it seems to me that if we have to have separate objects for each of the chef's tasks (which seems unnatural, given that the same person is doing all three function) then that seems to prioritize software design over the conceptual model. I feel an object oriented design is helpful here if we want to have, say, "meat_chef" "sous_chef" "three_star_chef" that are likely different people. Moreover, related to the runtime problem is that there is an overhead in complexity it seems, under the strict application of the single responsibility principle, that has to make sure the underlying data that make up the base class employee get changed and that this change is reflected in subsequent time steps.
I'm therefore rather tempted to leave it more or less as is. If somebody could clarify why this would be a bad idea (and if you have suggestions on how best to proceed) I'd be most obliged.
To avoid abusing class heirarchies now and in future, you should really only use it when an is relationship is present. As yourself, "is cook_food a kitchen_worker". It obviously doesn't make sense in real life, and doesn't in code either. "cook_food" is an action, so it might make sense to create an action class, and subclass that instead.
Having a new class just to add new methods like cook() and prep() isn't really an improvement on the original problem anyway - since all you've done is wrapped the method inside a class. What you really wanted was to make an abstraction to do any of these actions - so back to the action class.
class action {
public:
virtual void perform_action()=0;
}
class cook_food : public action {
public:
virtual void perform_action() {
//do cooking;
}
}
A chef can then be given a list of actions to perform in the order you specify. Say for example, a queue.
class chef {
...
perform_actions(queue<action>& actions) {
for (action &a : actions) {
a.perform_action();
}
}
...
}
This is more commonly known as the Strategy Pattern. It promotes the open/closed principle, by allowing you to add new actions without modifying your existing classes.
An alternative approach you could use is a Template Method, where you specify a sequence of abstract steps, and use subclasses to implement the specific behaviour for each one.
class dish_maker {
protected:
virtual void prep() = 0;
virtual void cook() = 0;
virtual void plate() = 0;
public:
void make_dish() {
prep();
cook();
plate();
}
}
class onion_soup_dish_maker : public dish_maker {
protected:
virtual void prep() { ... }
virtual void cook() { ... }
virtual void plate() { ... }
}
Another closely related pattern which might be suitable for this is the Builder Pattern
These patterns can also reduce of the Sequential Coupling anti-pattern, as it's all too easy to forget to call some methods, or call them in the right order, particularly if you're doing it multiple times. You could also consider putting your kitchen.opens() and closes() into a similar template method, than you don't need to worry about closes() being called.
On creating individual classes for onion_cutter and carrot_cutter, this isn't really the logical conclusion of the SRP, but in fact a violation of it - because you're making classes which are responsible for cutting, and holding some information about what they're cutting. Both cutting onions and carrots can be abstracted into a single cutting action - and you can specify which object to cut, and add a redirection to each individual class if you need specific code for each object.
One step would be to create an abstraction to say something is cuttable. The is relationship for subclassing is candidate, since a carrot is cuttable.
class cuttable {
public:
virtual void cut()=0;
}
class carrot : public cuttable {
public:
virtual void cut() {
//specific code for cutting a carrot;
}
}
The cutting action can take a cuttable object and perform any common cutting action that's applicable to all cuttables, and can also apply the specific cut behaviour of each object.
class cutting_action : public action {
private:
cuttable* object;
public:
cutting_action(cuttable* obj) : object(obj) { }
virtual void perform_action() {
//common cutting code
object->cut(); //specific cutting code
}
}
In order to make my code a bit clearer, I was trying to split a long piece of code into several methods (a little PHP-like).
I have a variable CurrentStep indicating the current screen to be rendered.
class Game
{
private:
enum Step { Welcome = 0, Menu, };
unsigned int CurrentStep;
}
Now I want to call the corresponding method when rendering the frame:
void Game::RenderFrame
{
switch (CurrentStep)
{
case Welcome:
// the actual work is done by WelcomeScreen() to keep this clean
WelcomeScreen(); break;
case Menu:
// same here
MenuScreen(); break;
}
}
I hope it is understandable what I was trying to achieve. Eventually it is supposed to call the appropriate method (at runtime).
However, this way is just that redundant... Isn't there a "better" way to go with C++?
I guess what you are looking for is the command pattern.
Read this detailed explanation (for C++)
http://www.dreamincode.net/forums/topic/38412-the-command-pattern-c/
to learn more about it.
First off, your private variable should be declared as Step CurrentStep; and RenderFrame() needs parentheses. Next, it's hard to give specific advice given how general and vague the question is, but in principle you could do something with inheritance:
class AbstractGameState
{
virtual ~AbstractGameState() { }
virtual void renderFrame() = 0;
};
class WelcomeScreenState : public AbstractGameState
{
void renderFrame(); // implement!
};
class MenuState : public AbstractGameState
{
void renderFrame(); // implement!
};
class Game
{
std::vector<std::shared_ptr<AbstractGameState> > gameStates;
public:
void renderFrame()
{
std::shared_ptr<AbstractGameState> state = getCurrentState(); // implement!
state->renderFrame();
}
};
We're going to need more information. If you make RenderFrame a virtual function, you can use run-time polymorphism to call the correct case of RenderFrame.
Besides the polymorphic approach that Kerrek posted (some would call it the classic object-oriented approach), there are other techniques that doesn't use polymorphism.
One of them are table driven methods
the other one worth mentioned is the visitor pattern, already efficiently implemented in the boost variant library. Here is an example that shows something similar to what you want to do
How many other states will you have?
Do the implementations of WelcomeScreen() and MenuScreen() have anything in common that can be moved into a common base class?
If the answer to the first question is "a few others" or the answer to the second is "not much" then your code is just fine. Keep things simple if you can.
Inheritance, the Command Pattern and other approaches that are suggested will complicate your code a bit while allowing more flexibility in adding more states in the future. You know your app better and know what its future holds.
I'm in a bit of a pickle: say I'm making a simple, 2D, Zelda-like game.
When two Objects collide, each should have a resulting action. However, when the main character collides with something, his reaction depends solely on the type of the object with which he collided. If it's a monster, he should bounce back, if it's a wall, nothing should happen, if it's a magical blue box with ribbons, he should heal, etc. (these are just examples).
I should also note that BOTH things are part of the collision, that is, collision events should happen for both the character AND the monster, not just one or the other.
How would you write code like this? I can think of a number of incredibly inelegant ways, for instance, having virtual functions in the global WorldObject class, to identify attributes - for instance, a GetObjectType() function (returns ints, char*s, anything that identifies the object as Monster, Box, or Wall), then in classes with more attributes, say Monster, there could be more virtual functions, say GetSpecies().
However, this becomes annoying to maintain, and leads to a large cascading switch (or If) statement in the collision handler
MainCharacter::Handler(Object& obj)
{
switch(obj.GetType())
{
case MONSTER:
switch((*(Monster*)&obj)->GetSpecies())
{
case EVILSCARYDOG:
...
...
}
...
}
}
There's also the option of using files, and the files would have things like:
Object=Monster
Species=EvilScaryDog
Subspecies=Boss
And then the code can retrieve the attributes without the need for virtual functions cluttering everything up. This doesn't solve the cascading If problem, however.
And THEN there's the option of having a function for each case, say CollideWall(), CollideMonster(), CollideHealingThingy(). This is personally my least favourite (although they're all far from likeable), because it seems the most cumbersome to maintain.
Could somebody please give some insight into more elegant solutions to this problem?
Thanks for any and all help!
I would do it vice versa - because if the character collides with an object, an object collides with the character as well. Thus you can have a base class Object, like this:
class Object {
virtual void collideWithCharacter(MainCharacter&) = 0;
};
class Monster : public Object {
virtual void collideWithCharacter(MainCharacter&) { /* Monster collision handler */ }
};
// etc. for each object
Generally in OOP design virtual functions are the only "correct" solution for cases like this:
switch (obj.getType()) {
case A: /* ... */ break;
case B: /* ... */ break;
}
EDIT:
After your clarification, you will need to adjust the above a bit. The MainCharacter should have overloaded methods for each of the objects it can collide with:
class MainCharacter {
void collideWith(Monster&) { /* ... */ }
void collideWith(EvilScaryDog&) { /* ... */ }
void collideWith(Boss&) { /* ... */ }
/* etc. for each object */
};
class Object {
virtual void collideWithCharacter(MainCharacter&) = 0;
};
class Monster : public Object {
virtual void collideWithCharacter(MainCharacter& c)
{
c.collideWith(*this); // Tell the main character it collided with us
/* ... */
}
};
/* So on for each object */
This way you notify the main character about the collision and it can take appropriate actions. Also if you need an object that should not notify the main character about the collision, you can just remove the notification call in that particular class.
This approach is called a double dispatch.
I would also consider making the MainCharacter itself an Object, move the overloads to Object and use collideWith instead of collideWithCharacter.
How about deriving all collidable objects from one common abstract class (let's call it Collidable). That class could contain all properties that can be changed by a collission and one HandleCollision function. When two objects collide, you just call HandleCollision on each object with the other object as the argument. Each object manipulates the other to handle the collision. Neither object needs to know what other object type it just bounced into and you have no big switch statements.
Make all colidable entities implement an interface (lets say "Collidable") with a collideWith(Collidable) method.
Then, on you collision detection algorithm, if you detect that A collides with B, you would call:
A->collideWith((Collidable)B);
B->collideWith((Collidable)A);
Assume that A is the MainCharacter and B a monster and both implement the Collidable interface.
A->collideWith(B);
Would call the following:
MainCharacter::collideWith(Collidable& obj)
{
//switch(obj.GetType()){
// case MONSTER:
// ...
//instead of this switch you were doing, dispatch it to another function
obj->collideWith(this); //Note that "this", in this context is evaluated to the
//something of type MainCharacter.
}
This would in turn call the Monster::collideWith(MainCharacter) method and you can implement all monster-character behaviour there:
Monster::CollideWith(MainCharacter mc){
//take the life of character and make it bounce back
mc->takeDamage(this.attackPower);
mc->bounceBack(20/*e.g.*/);
}
More info: Single Dispatch
Hope it helps.
What you call "an annoying switch statement" i would call "a great game" so you are on the right track.
Having a function for every interaction/game rule is exactly what I would suggest. It makes it easy to find, debug, change and add new functionality:
void PlayerCollidesWithWall(player, wall) {
player.velocity = 0;
}
void PlayerCollidesWithHPPotion(player, hpPoition) {
player.hp = player.maxHp;
Destroy(hpPoition);
}
...
So the question is really how to detect each of these cases. Assuming you have some sort of collision detection that results in X and Y collide (as simple as N^2 overlap tests (hey, it works for plants vs zombies, and that's got a lot going on!) or as complicated as sweep and prune + gjk)
void DoCollision(x, y) {
if (x.IsPlayer() && y.IsWall()) { // need reverse too, y.IsPlayer, x.IsWall
PlayerCollidesWithWall(x, y); // unless you have somehow sorted them...
return;
}
if (x.IsPlayer() && y.IsPotion() { ... }
...
This style, while verbose is
easy to debug
easy to add cases
shows you when you have
logical/design inconsistencies or
omissions "oh what if a X is both a
player and a wall due to the
"PosessWall" ability, what then!?!"
(and then lets you simply add cases
to handle those)
Spore's cell stage uses exactly this style and has approximately 100 checks resulting in about 70 different outcomes (not counting the param reversals). It's only a ten minute game, that's 1 new interaction every 6 seconds for the whole stage - now that's gameplay value!
If I am getting your problem correctly, I would sth like
Class EventManager {
// some members/methods
handleCollisionEvent(ObjectType1 o1, ObjectType2 o2);
// and do overloading for every type of unique behavior with different type of objects.
// can have default behavior as well for unhandled object types
}