I have a c++ program in which I:
Have a class which contains, as members, function handles, say void (*foo) and void (*bar)
Have a collection of namespaces, each defining functions of the same name, e.g.:
namespace1 contains functions void foo() and void bar()
namespace2 also contains functions void foo() and void bar()
At run-time, I would like the user to be able to pass a variable, say choice, which indicates the chosen namespace. The functions in the class would then be mapped to the corresponding functions in the appropriate namespace.
Currently, I'm using something along the following lines:
if (choice == "namespace1") {
my_class.foo = &(namespace1::foo);
my_class.bar = &(namespace1::bar);
} else if (choice == "namespace2") {
my_class.foo = &(namespace2::foo);
my_class.bar = &(namespace2::bar);
}
This works well, but becomes rather cumbersome when my list of available namespaces increases and given that each namespace provides 9 functions that I would like to pass into the class.
Are there ways that I can tidy this up? My first thought was something like:
if (choice == "namespace1") {
my_namespace = namespace1;
} else if (choice == "namespace2") {
my_namespace = namespace2;
}
my_class.foo = &(my_namespace::foo);
my_class.bar = &(my_namespace::bar);
But, if I understand correctly, I cannot use namespaces as variables.
Is there a better way to formulate this? As structured, is this poor style and, is there a more standard way to go about this?
Thank you for any insights that you might have!
You should be aware of the phases of compilation, at least approximately. Names simply do not exist at runtime. Your existing code works by creating pointers for each and every name within each namespace.
The standard solution is to define an interface.
class IFooBar {
virtual void foo() = 0;
virtual void bar() = 0;
// Other 7 functions.
};
This allows each namespace to define one class instead of 9 functions.
Chances are that the compiler behind the scenes creates a "vtable", an array of function pointers, to implement this interface. This would be approximately the same as you do now, but then automated and without the chance of copy-paste errors.
I suggest using traits.
template<Context C>
struct context;
template<NAMESPACE_1> struct context<> {
static foo_return_t foo(...) {
return namespace1::foo (...);
}
static bar_return_t bar(...) {
return namespace1::bar (...);
}
};
template<NAMESPACE_2> struct context<> {
static foo_return_t foo(...) {
return namespace2::foo (...);
}
static bar_return_t bar(...) {
return namespace2::bar (...);
}
};
Then use like so:
foo_ret_t a;
bar_ret_t b;
if (choice == "namespace1") {
a = context<NAMESPACE_1>::foo(...);
b = context<NAMESPACE_1>::bar(...);
} else if (choice == "namespace1") {
a = context<NAMESPACE_2>::foo(...);
b = context<NAMESPACE_2>::bar(...);
}
Your problem is that the stuff is evaluated at runtime.
To expand on the the answer by #MSalters ...
There is a design pattern that addresses this situation. It is called the Dependency Injection Pattern.
Your class (where you are trying to store foo and bar) is the client.
The namespaces contain classes that implement the interface.
A dependency injector will need to inject the dependency (a pointer to one of the concrete classes in the namespaces) into the client.
Related
I have a class whose member itemType is only set once and never modified but it is used in many if-statements to decide which function to call.
Since itemType is only set once is there way to avoid the if statements else where in the class. This will simplify and clean the code and as a bonus will also save the overhead of if checks.
I was thinking about function a pointer taht I can initiatlize in the constructor based on the itemType value.
Is there any alternate and a better way of doing that?
Please note the original class and code base is large and I cant go around creating child classes based on itemtype.
enum ItemTypes
{
ItemTypeA,
ItemTypeB,
};
class ItemProcessing
{
public:
//This function is called hundreds of times
void ProcessOrder(Order* order)
{
//This member itemType is set only once in the constructor and never modified again
//Is there a way to not check it all the time??
if (itemtype == ItemTypes::ItemTypeA )
{
ProcessTypeA(order)
}
else if (itemtype == ItemTypes::ItemTypeB )
{
ProcessTypeB(order)
}
}
ItemProcessing(ItemTypes itype)
{
itemtype = itype; //can I do something here like setting a function pointer so I dont have to check this property in ProcessOrder() and call the relevant function directly.
}
private:
ItemTypes itemtype;
void ProcessTypeA(Order*);
void ProcessTypeB(Order*);
};
Use an array of function pointers, indexed by itemtype, like this:
typedef void(*ProcessType_func_t)(Order *);
ProcessType_func_t processType_f[] = {
ProcessTypeA,
ProcessTypeB
};
Then you can do:
void ProcessOrder(Order *order) {
ProcessType_f[itemtype](order);
}
If you have lots of different functions that need to be dispatched like this, you can use a structure.
struct {
ProcessType_func_t processType_f,
OtherType_func_t otherType_f,
...
} dispatchTable[] = {
{ ProcessTypeA, OtherTypeA, ... },
{ ProcessTypeB, OtherTypeB, ... }
};
Then you would use it as:
dispatchTable[itemtype].processType_f(order);
Finally, you could do the fully object-oriented method, by defining new classes:
class Processor { // abstract base class
public:
virtual void Process(Order *order) = 0;
};
class ProcessorA {
public:
void Process(Order *order) {
ProcessTypeA(order);
}
}
class ProcessorB {
public:
void Process(Order *order) {
ProcessTypeB(order);
}
}
Then you can have a member variable
Processor *processor;
and you initialize it when you set itemtype
ItemProcessing(ItemTypes itype)
{
itemtype = itype;
if (itemtype == ItemTypeA) {
processor = new ProcessorA;
} else {
processor = new ProcessorB;
}
}
Then you would use it as:
processor->Process(order);
This is easily expanded to support more functions that need to dispatch on itemtype -- they all become methods in the classes.
I hope I got the syntax right, I don't actually do much C++ OO programming myself.
You can consider to use either a couple of pointers to member methods or the state pattern.
The former solution has probably higher performance, while the latter is more elegant and flexible (at least from my point of view).
For further details on the state pattern, see here. This pattern fits well with your problem, even though you have to refactor a bit your classes.
I guess the first suggestion is indeed quite clear and does not require further details.
In c++ pointer to function should be mimic with virtual function and inheritance. (Polymorphism)
Define a virtual class including a pure virtual methods
processOrder ( Order* ordre);
And define subclass for each value of your enum.
You can use abstract factory pattern to creat those object or either if needed.
I can write the code if wish.
I'm trying to study by myself the OOP and I wanted to know if what I am doing is correct or if it is an anti-pattern. Is it OK to use a global function inside a class? for example:
bool isMale(char s)
{
if(s=='m')return true;
else return false;
}
class person
{
string name; char sex;
bool collocate()
{
if(isMale(sex))cout<<"He's a male!";
else cout<<"She's not!";
}
}
I know this is a very stupid code but I was just trying to explain myself. Is it indicated to use global function inside a class or is it a bad-habit? Should I use other ways or is it OK?
Thanks.
You can do it, yes, and it is not considered an anti-pattern. It is quite often an elegant solution as well.
It is also usually a good idea to wrap your global functions into a namespace
There's nothing wrong with using global functions in C++; the language is a superset of C and global functions are C's bread and butter. A benefit of using a global function is that it doesn't rely on an object being instantiated before the function can be called. This can make the function far easier to test in isolation.
Generally when writing code in this fashion I put my functions into a class and make them static, though. This negates the possibility of writing a function with the same name as some standard library function since it's in a different namespace. i.e:
class Person
{
public:
static bool isMale( char gender )
{
return gender == 'm';
}
bool collocate()
{
if( isMale( m_sex ) )
cout << "He's a male!" << endl;
else
cout << "She's not!" << endl;
}
private:
/// m/f
char m_sex;
/// Person Name
String m_name;
};
Since this method seems to be intimately related to person class, it can be a static method of the class. If you can imagine needing the function without having person class included, and decide that the same function should indeed be used both for person class objects and for everything else, then a global function in a suitable namespace is better. If the method is used by many related classes, but does not seem to belong to any class, then the classes and these helper functions should be neatly in the same namespace.
class person
{
private:
string name;
char sex;
public:
static bool isMale(char s)
{
if(s=='m')return true;
else return false;
}
bool collocate()
{
if(isMale(sex))cout<<"He's a male!";
else cout<<"She's not!";
}
}
You can do it. Yes. Not everything is an object in C++.
This is ok (although isMale needs an argument). ^^
In fact, only functions that really need access to the representation of a class should be memberfunctions. That way, you have fewer functions to worry about if you change your class-representation while keeping its interface.
I have a very simple class definition as follows:
#include "../bshttp/controllers.h"
#include <iostream>
#include <string>
class DerivedController : public BS_Controllers
{
public:
DerivedController():BS_Controllers(this)
{
m_urlRules["print"] = REG_NAME &DerivedController::print;
//regController(REG_NAME &DerivedController::print,"print");
regController(REG_NAME &DerivedController::printView,"printView");
}
void * print()
{
return NULL;
}
void * printView()
{
cout<<"Print view!"<<endl;
return NULL;
}
};
where either
m_urlRules["print"] = REG_NAME &DerivedController::print;
or
regController(REG_NAME &DerivedController::printView,"printView");
has to be called for all of the member functions. What it does it that it takes the member function pointer of the class and maps with a string, so later on the function can be identified with a string.
Everything is all well and working, but when the class structure gets bigger, the programmer will have to repetitively call this function for every single member function. Is there anyway to use the preprocessor, or any preprocessing library such as the boost-wave, so that the programmer doesn't have to do these repetitive calling?
EDIT:
Sorry for the confusion, I clearly did not describe the problem well enough here.
I am mapping strings to member function pointer;
m_urlRules is a std::map with string as the key, and member function pointer as value
regController is basically a setter function for m_urlRules, so both statements effectively does the same thing, which maps a string to a member function.
REG_NAME is a macro to replace a very ugly typecast.
what I am trying to do is that, if the class where to have the following structure,
class DerivedController : public BS_Controllers
{
public:
DerivedController():BS_Controllers(this);
void * print();
void * print2();
void * print3();
void * print4();
};
I dont have to do the following in the constructor:
m_urlRules["print"] = REG_NAME &DerivedController::print;
m_urlRules["print1"] = REG_NAME &DerivedController::print1;
m_urlRules["print2"] = REG_NAME &DerivedController::print2;
m_urlRules["print3"] = REG_NAME &DerivedController::print3;
m_urlRules["print4"] = REG_NAME &DerivedController::print4;
Well, you're trying to build the runtime type information (RTTI) on your own, so no there is no preprocessor macro for this. Mainly because preprocessor macros expand to a single place, and the place where you declare, and the place, where you register your functions are different.
Qt and qmake, does something like this, it finds the functions marked signals/slots, and builds a moc object for RTTI. That's about the best you can get with c++. Other languages like java, and delphi, has more RTTI, than c++, and makes it possible to query functions at runtime.
I am not exactly sure I understood completely your problem, but why don't use the built-in data structure, such as map, in which you can map it to a key (your string).
Here some examples
I would first work on removing the ugly typecast (even in macro form). This can be done by moving the m_urlRules out of BS_Controllers and into an intermediate (or proxy) template class. The template is used to resolve the map to the right derived type. (I didn't know how you defined BS_Controllers, so I made one up.)
class BS_Controllers {
protected:
virtual ~BS_Controllers () {}
public:
virtual void * invokeRule (const std::string &) = 0;
};
template <typename D>
class BS_Proxy : public BS_Controllers {
typedef std::map<std::string, void *(D::*)()> UrlRuleMap;
static UrlRuleMap & urlRules () {
static UrlRuleMap urlRules_;
return urlRules_;
}
void * invokeRule (const std::string &s) {
typename UrlRuleMap::iterator i = urlRules().find(s);
if (i == urlRules().end()) return 0;
return (dynamic_cast<D *>(this)->*(i->second))();
}
protected:
static void regController (void *(D::*m)(), const std::string &s) {
urlRules()[s] = m;
}
};
Now, the DerivedController can be initialized fairly easily, by invoking the regController method of the proxy class.
#define REG_RULE(D, x) BS_Proxy<D>::regController(&D::x, #x)
class DerivedController : public BS_Proxy<DerivedController> {
struct Populate {
Populate () {
REG_RULE(DerivedController, print);
REG_RULE(DerivedController, printView);
}
};
public:
DerivedController() {
static Populate populate_;
}
void * print() { return NULL; }
void * printView() {
std::cout<<"Print view!"<<std::endl;
return NULL;
}
};
You can view a demo of the above code.
If you want to make the population semi-automatic, you still have to define the list of methods somewhere. You could list them out in a file.
// DerivedController rules
DERIVED_RULE_INC(print)
DERIVED_RULE_INC(printView)
//...
And then change your DerivedController class to use this file:
class DerivedController : public BS_Proxy<DerivedController> {
struct Populate {
Populate () {
#define DERIVED_RULE_INC(x) REG_RULE(DerivedController, x);
#include "derived_controller_rules.inc"
#undef DERIVED_RULE_INC
}
};
public:
DerivedController() {
static Populate populate_;
}
#define DERIVED_RULE_INC(x) void * x ();
#include "derived_controller_rules.inc"
#undef DERIVED_RULE_INC
};
void * DerivedController::print() { return NULL; }
void * DerivedController::printView() {
std::cout<<"Print view!"<<std::endl;
return NULL;
}
Now, if you add another rule to the file, the registration code and the method declaration is automatic. But the definition of the method needs to be implemented, or a linker error will be generated about the missing method definition.
I believe you want to use this feature for logging reasons, to see where problems appear.
I think you're searching for something like:
urlRules ("<function name>");
regController("<function name>");
Instead of
m_urlRules["<function name>"] = REG_NAME &DerivedController::print;
regController(REG_NAME &DerivedController::printView,"<function name>");
You can define such makros like so:
#define urlRules(x) { m_urlRules[(x)] = REG_NAME &DerivedController::print; }
#define regController(x) { regController(REG_NAME &DerivedController::printView,(x)); }
Attention: I have not tested it, it might not work but in my understanding it should.
EDIT:
Ah now I understand, you want calls for every function within the constructor.
Actually, the constructor is the wrong place, because it gets called for every object you create, but you only have to assign this pointers once. (on startup for example)
See, the functions of a class only exist once in memory, and the thing that is connected to the pointer is the yield data, so all member variables.
There is no simple way to get all class members by name and then run over them, sorry.
At least not as I know of.
But you should keep in mind that the function pointers won't change for any given object.
An external function which does the work would be more intelligent. Called on startup.
I'm trying to figure out why some code bases use IsA() to determine object polymorphism if in C++ you can already safely upcast and down cast (using dynamic_cast) ?
So far the only case I see useful is when you are integrating a a scripting environment that is linked to the c++ codebase?
Thanks!
There are few reasons where and IsA() function, or even a dynamic_cast<>() are needed in C++. The worst examples of this type of code are the giant if-then statements using dynamic_casts, or switch statements on a type field. These represent a maintenance nightmare, where adding a class can involve updating dozens, or hundreds of different locations to support the new class.
For example:
Bad:
// Don't do this:
void PrintName(Base *b, ostream &o)
{
if (dynamic_cast<DerivedA *>(b) != NULL)
o << "Derived A";
if (dynamic_cast<DerivedB *>(b) != NULL)
o << "Derived B";
if (dynamic_cast<DerivedC *>(b) != NULL)
o << "Derived C";
}
Better:
void PrintName(Base *b, ostream &o)
{
o << b->GetName();
}
This is obviously eliding checking for null, and using smart pointers, etc.. Likewise, if you're querying the type to choose between different behaviours, you need to ask why you're doing something different for each type, and move that behaviour decision into the object.
Bad:
// Don't do this:
void ObjectBase::ApplyForceToObject(const Force &f)
{
if (dynamic_cast<Wall*>(this) != NULL
|| dynamic_cast<Floor*>(b) != NULL)
{
// Do nothing
}
else
{
// Accelerate object
}
}
Better:
void ObjectBase::ApplyForceToObject(const Force &f)
{
if (IsFixedObject())
{
// Do nothing
}
else
{
// Accelerate object
}
}
...
bool ObjectBase::IsFixedObject() { return false; }
bool Wall::IsFixedObject() { return true; }
bool Floor::IsFixedObject() { return true; }
In modern C++ there is no point.
Frameworks dating from before the 1998 standardization may offer an IsA function.
E.g. as I recall there is such functionality in MFC.
Also, as you note, when dealing with objects implemented in other languages (with types not represented by C++ types) it may conceivably be useful.
Cheers & hth.,
Because dynamic-cast relies on RTTI, and this can hurt performance. It is also a bit more convinient and reliable.
Sometimes you dont have RTTI ( maybe you're working on a memory/cpu constrained system and disabling RTTI is the mandated solution) In that case you don't have dynamic_cast available to you. If you want to use something similar to RTTI you usually end up with solutions that are IsA() with static_cast.
Another possible use for an IsA() function is when you don't know all your classes at compile-time (maybe they've been loaded from shared library), or you dont want to list all the types explicitly. This lets you write things like
handleInstance( Instance * i )
{
//libs has been filled through loading dynamic libraries.
for( auto it = libs.begin() ; it!=libs.end() ; ++it )
{
if( i->IsA( it->type_key ) )
{
it->process( i );
}
}
}
Though in this case I might turn the test condition inside out like
if( it->can_process( i ) )
and can_process would be free to use dynamic_cast.
An example of how to find run time type information without RTTI
MFC uses a function called IsKindOf() for run time type information. The method MFC uses to find type information is somewhat like the example below.
#define RUNTIME_CLASS(class_name) (class_name::GetThisClass())
#define RUNTIME_OBJ(class_name) (class##class_name)
struct RunTimeClass
{
string name;
};
class base
{
static RunTimeClass RUNTIME_OBJ(base); //watch the naming
public:
bool IsExactKind(RunTimeClass* pRTclass)
{
if(pRTclass == GetRunTimeClass())
{
return true;
}
return false;
}
static RunTimeClass* GetThisClass()
{
return &RUNTIME_OBJ(base);
}
virtual RunTimeClass* GetRunTimeClass()
{
return &RUNTIME_OBJ(base);
}
virtual ~base() = 0;
};
class derived: public base
{
static RunTimeClass RUNTIME_OBJ(derived); //watch the naming
public:
RunTimeClass* GetRunTimeClass()
{
return &RUNTIME_OBJ(derived);
}
static RunTimeClass* GetThisClass()
{
return &RUNTIME_OBJ(derived);
}
};
class derived2: public derived
{
static RunTimeClass RUNTIME_OBJ(derived2); //watch the naming
public:
RunTimeClass* GetRunTimeClass()
{
return &RUNTIME_OBJ(derived2);
}
static RunTimeClass* GetThisClass()
{
return &RUNTIME_OBJ(derived2);
}
};
In the cpp file
RunTimeClass base::classbase = {"base"}; //not using the macro RUNTIME_OBJ
RunTimeClass derived::classderived = {"derived"}; //not using the macro RUNTIME_OBJ
RunTimeClass derived2::classderived2 = {"derived2"}; //not using the macro RUNTIME_OBJ
base::~base() {}
void main()
{
derived *ptrDer = new derived();
bool isder = ptrDer->IsExactKind(RUNTIME_CLASS(derived));
derived2 *ptrDer2 = new derived2();
isder = ptrDer2->IsExactKind(RUNTIME_CLASS(derived2));
delete ptrDer;
delete ptrDer2;
}
Note that this can only find if the object is of the exact class type. To add type information you just need to inherit from base and add a Runtimeclass variable and implement two functions getthisclass(), getruntimeclass(). MFC use CObject as the base class which provides similiar functionality. Also, there are more macros to make your life easier. IsKindOF() function in MFC walk thourgh the entire hierarchy and find out the object "is a" type of class(which is not there in my scaled down version). You can see this is somewhat similiar to RTTI, hence I guess there is no perfomance difference. It is there in MFC because it was there before RTTI.
So, if there is an IsA() function which perfoms better than RTTI, I would like to see the implementation.
I have a set of classes that describe a set of logical boxes that can hold things and do things to them. I have
struct IBox // all boxes do these
{
....
}
struct IBoxCanDoX // the power to do X
{
void x();
}
struct IBoxCanDoY // the power to do Y
{
void y();
}
I wonder what is the 'best' or maybe its just 'favorite' idiom for a client of these classes to deal with these optional capabilities
a)
if(typeid(box) == typeid(IBoxCanDoX))
{
IBoxCanDoX *ix = static_cast<IBoxCanDoX*>(box);
ix->x();
}
b)
IBoxCanDoX *ix = dynamic_cast<IBoxCanDoX*>(box);
if(ix)
{
ix->x();
}
c)
if(box->canDoX())
{
IBoxCanDoX *ix = static_cast<IBoxCanDoX*>(box);
ix->x();
}
d) different class struct now
struct IBox
{
void x();
void y();
}
...
box->x(); /// ignored by implementations that dont do x
e) same except
box->x() // 'not implemented' exception thrown
f) explicit test function
if(box->canDoX())
{
box->x();
}
I am sure there are others too.
EDIT:
Just to make the use case clearer
I am exposing this stuff to end users via interactive ui. They can type 'make box do X'. I need to know if box can do x. Or I need to disable the 'make current box do X' command
EDIT2: Thx to all answerers
as Noah Roberts pointed out (a) doesnt work (explains some of my issues !).
I ended up doing (b) and a slight variant
template<class T>
T* GetCurrentBox()
{
if (!current_box)
throw "current box not set";
T* ret = dynamic_cast<T*>(current_box);
if(!ret)
throw "current box doesnt support requested operation";
return ret;
}
...
IBoxCanDoX *ix = GetCurrentBox<IBoxCanDoX>();
ix->x();
and let the UI plumbing deal nicely with the exceptions (I am not really throwing naked strings).
I also intend to explore Visitor
I suggest the Visitor pattern for double-dispatch problems like this in C++:
class IVisitor
{
public:
virtual void Visit(IBoxCanDoX *pBox) = 0;
virtual void Visit(IBoxCanDoY *pBox) = 0;
virtual void Visit(IBox* pBox) = 0;
};
class IBox // all boxes do these
{
public:
virtual void Accept(IVisitor *pVisitor)
{
pVisitor->Visit(this);
}
};
class BoxCanDoY : public IBox
{
public:
virtual void Accept(IVisitor *pVisitor)
{
pVisitor->Visit(this);
}
};
class TestVisitor : public IVisitor
{
public:
// override visit methods to do tests for each type.
};
void Main()
{
BoxCanDoY y;
TestVisitor v;
y.Accept(&v);
}
Of the options you've given, I'd say that b or d are "best". However, the need to do a lot of this sort of thing is often indicative of a poor design, or of a design that would be better implemented in a dynamically typed language rather than in C++.
If you are using the 'I' prefix to mean "interface" as it would mean in Java, which would be done with abstract bases in C++, then your first option will fail to work....so that one's out. I have used it for some things though.
Don't do 'd', it will pollute your hierarchy. Keep your interfaces clean, you'll be glad you did. Thus a Vehicle class doesn't have a pedal() function because only some vehicles can pedal. If a client needs the pedal() function then it really does need to know about those classes that can.
Stay way clear of 'e' for the same reason as 'd' PLUS that it violates the Liskov Substitution Principle. If a client needs to check that a class responds to pedal() before calling it so that it doesn't explode then the best way to do that is to attempt casting to an object that has that function. 'f' is just the same thing with the check.
'c' is superfluous. If you have your hierarchy set up the way it should be then casting to ICanDoX is sufficient to check if x can do X().
Thus 'b' becomes your answer from the options given. However, as Gladfelter demonstrates, there are options you haven't considered in your post.
Edit note: I did not notice that 'c' used a static_cast rather than dynamic. As I mention in an answer about that, the dynamic_cast version is cleaner and should be preferred unless specific situations dictate otherwise. It's similar to the following options in that it pollutes the base interface.
Edit 2: I should note that in regard to 'a', I have used it but I don't use types statically like you have in your post. Any time I've used typeid to split flow based on type it has always been based on something that is registered during runtime. For example, opening the correct dialog to edit some object of unknown type: the dialog governors are registered with a factory based on the type they edit. This keeps me from having to change any of the flow control code when I add/remove/change objects. I generally wouldn't use this option under different circumstances.
A and B require run time type identification(RTTI) and might be slower if you are doing a lot checks. Personally I don't like the solutions of "canDoX" methods, if situations like this arise the design probably needs an upgrade because you are exposing information that is not relevant to the class.
If you only need to execute X or Y, depending on the class, I would go for a virtual method in IBox which get overridden in subclasses.
class IBox{
virtual void doThing();
}
class IBoxCanDoX: public IBox{
void doThing() { doX(); }
void doX();
}
class IBoxCanDoY: public IBox{
void doThing() { doY(); }
void doY();
}
box->doThing();
If that solution is not applicable or you need more complex logic, then look at the Visitor design pattern. But keep in mind that the visitor pattern is not very flexible when you add new classes regularly or methods change/are added/are removed (but that also goes true for your proposed alternatives).
If you are trying to call either of these classes actions from contingent parts of code, you I would suggest you wrap that code in a template function and name each class's methods the same way to implement duck typing, thus your client code would look like this.
template<class box>
void box_do_xory(box BOX){
BOX.xory();
}
There is no general answer to your question. Everything depends. I can say only that:
- don't use a), use b) instead
- b) is nice, requires least code, no need for dummy methods, but dynamic_cast is a little slow
- c) is similar to b) but it is faster (no dynamic_cast) and requires more memory
- e) has no sense, you still need to discover if you can call the method so the exception is not thrown
- d) is better then f) (less code to write)
- d) e) and f) produce more garbage code then others, but are faster and less memory consuming
I assume that you will not only be working with one object of one type here.
I would lay out the data that you are working with and try to see how you can lay it out in memory in order to do data-driven programming. A good layout in memory should reflect the way that you store the data in your classes and how the classes are layed out in memory. Once you have that basic design structured (shouldn't take more than a napkin), I would begin organizing the objects into lists dependent on the operations that you plan to do on the data. If you plan to do X() on a collection of objects { Y } in the subset X, I would probably make sure to have a static array of Y that I create from the beginning. If you wish to access the entire of X occasionally, that can be arranged by collecting the lists into a dynamic list of pointers (using std::vector or your favorite choice).
I hope that makes sense, but once implemented it gives simple straight solutions that are easy to understand and easy to work with.
There is a generic way to test if a class supports a certain concept and then to execute the most appropriate code. It uses SFINAE hack. This example is inspired by Abrahams and Gurtovoy's "C++ Template Metaprogramming" book. The function doIt will use x method if it is present, otherwise it will use y method. You can extend CanDo structure to test for other methods as well. You can test as many methods as you wish, as long as the overloads of doIt can be resolved uniquely.
#include <iostream>
#include <boost/config.hpp>
#include <boost/utility/enable_if.hpp>
typedef char yes; // sizeof(yes) == 1
typedef char (&no)[2]; // sizeof(no) == 2
template<typename T>
struct CanDo {
template<typename U, void (U::*)()>
struct ptr_to_mem {};
template<typename U>
static yes testX(ptr_to_mem<U, &U::x>*);
template<typename U>
static no testX(...);
BOOST_STATIC_CONSTANT(bool, value = sizeof(testX<T>(0)) == sizeof(yes));
};
struct DoX {
void x() { std::cout << "doing x...\n"; }
};
struct DoAnotherX {
void x() { std::cout << "doing another x...\n"; }
};
struct DoY {
void y() { std::cout << "doing y...\n"; }
};
struct DoAnotherY {
void y() { std::cout << "doing another y...\n"; }
};
template <typename Action>
typename boost::enable_if<CanDo<Action> >::type
doIt(Action* a) {
a->x();
}
template <typename Action>
typename boost::disable_if<CanDo<Action> >::type
doIt(Action* a) {
a->y();
}
int main() {
DoX doX;
DoAnotherX doAnotherX;
DoY doY;
DoAnotherY doAnotherY;
doIt(&doX);
doIt(&doAnotherX);
doIt(&doY);
doIt(&doAnotherY);
}