Sign in to follow this  
NIm

Multiple purposes for a function in c++

Recommended Posts

I have a class, (module; it describes a module in a spaceship) and I'm making each module able to ahve a specific action(). the action can do several different things. It can fire a weapon, engage the engines, smelt some ore, or any number of things. not all of these functions require the same types of arguments. Is there any way I can generically pass arguments to the function, so that I can give coordinates to a gun, and a magnitude to a engine?

Share this post


Link to post
Share on other sites
No, but there are a variety of design patterns around this sort of specific problem; the interpreter strikes me as the first I'd look into.

Share this post


Link to post
Share on other sites
One word.... Abstract base class.


class ActionArgs
{
// code here
};

class Module
{
public:
virtual void Action(ActionArgs * pArgs) throw() = 0;
};

class EngineArgs : public ActionArgs
{
// code here
};

class Engine : public Module
{
public:
virtual void Action(ActionArgs * pArgs) throw()
{
EngineArgs * pEngineArgs = dynamic_cast<EngineArgs *>(pArgs);

// do your code with pEngineArgs
}
};

Share this post


Link to post
Share on other sites
There are ways to do it, and there are better ways to do it, and there is probably an even better way to solve your problem without doing it. Since the calling code knows what kind of parameters to provide, it must also know the class and member function that it is calling. Why then must the parameters be in a generic form?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by NIm
I have a class, (module; it describes a module in a spaceship) and I'm making each module able to ahve a specific action(). the action can do several different things. It can fire a weapon, engage the engines, smelt some ore, or any number of things. not all of these functions require the same types of arguments. Is there any way I can generically pass arguments to the function, so that I can give coordinates to a gun, and a magnitude to a engine?


it's hard to properly answer your question without having had a look into your current design, and without knowing how much of your existing design must remain unaltered, however in general there are really many ways to accomplish this, some of which are more invasive than others, for example:


- you could simply override your action methods for each individual type of action, as long as the method signatures are different, there should be no problems:
class CSpaceShipModule {
void action(coordinates& c);
void action(magnittude& m);
void action(direction& d);
void action(force& f);
};


In general however, it should be considered bad style to implement multiple identically-named functions that serve completely different purposes, without making the purpose more obvious-be it by naming the action properly in the first place, or by providing a corresponding "mode" flag:

class CSpaceShipModule {
public:
enum action_mode {FIRE,ENGAGE,ORE};
void action(action_mode m, parameterContainer& pC) {}
private:
};




- you could also define object-specific global functions that implement your actions:


void fire(const CSpaceshipModule& s) {}
void engageEngine(const CSpaceModule& s) {}



So, basically what I am saying: you may want to reconsider your current design and provide some background info about it, so that we can also provide more informed advice.

Share this post


Link to post
Share on other sites
This striked me as a good design:
class Container {
public:
float getSomeFuel(float pHowMuch) {
if( mFuel < pHowMuch ) {
float fuel = mFuel;
mFuel = 0.0f;
return fuel;
}
return
}
void fill(float pHowMuch) {
mFuel += pHowMuch;
}
private:
float mFuel;
};

class EngineModule : public Module {
public:
void action() {
float fuel = mFuelContainer->getSomeFuel(1.0f);
thrust(fuel);
}
void setFuelContainer(Container* pConatiner) {mFuelContainer = pContainer;}
private:
Container* mFuelContainer;
};

// The gun works the same way since it only fires in one direction

class MelterModule {
public:
void setInContainer(Container* pConatiner) {mInContainer = pContainer;}
void setOutContainer(Container* pConatiner) {mOutContainer = pContainer;}
void action() {
mOutContainer.fill( mInContainer.getSomeFuel(1.0f) );
}
private:
Container* mInContainer;
Container* mOutContainer;
};



If you need more control over how you should control the modules you need a different interface.

Share this post


Link to post
Share on other sites
Quote:
Original post by NIm
Is there any way I can generically pass arguments to the function, so that I can give coordinates to a gun, and a magnitude to a engine?


Not directly, no. Your compiler will demand that you pass the right number and type of parameters to any function you call, as specified by their signatures, which are checked at compile time. Unless you encode all the possible parameters into a common type (e.g. a string), and are ready to have each function explicitely unpack its parameters and check them for correctness (see here for some ideas), you will not be able to treat them polymorphically.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this