Whilst refactoring some legacy C++ code I found that I could potentially remove some code duplication by somehow defining a variable that could point to any class method that shared the same signature. After a little digging, I found that I could do something like the following:
class MyClass
{
protected:
bool CaseMethod1( int abc, const std::string& str )
{
cout << "case 1:" << str;
return true;
}
bool CaseMethod2( int abc, const std::string& str )
{
cout << "case 2:" << str;
return true;
}
bool CaseMethod3( int abc, const std::string& str )
{
cout << "case 3:" << str;
return true;
}
public:
bool TestSwitch( int num )
{
bool ( MyClass::*CaseMethod )( int, const std::string& );
switch ( num )
{
case 1: CaseMethod = &MyClass::CaseMethod1;
break;
case 2: CaseMethod = &MyClass::CaseMethod2;
break;
case 3: CaseMethod = &MyClass::CaseMethod3;
break;
}
...
bool res = CaseMethod( 999, "hello world" );
...
reurn res;
}
};
My question is - is this the correct way to go about this? Should I consider anything that Boost has to offer?
Edit...
Ok, my mistake - I should be calling the method like so:
bool res = ( (*this).*CaseMethod )( 999, "Hello World" );
What you have there is a pointer-to-member-function. It will solve your problem. I am surprised that your "TestSwitch" function compiles, as the calling syntax is slightly different to what you might expect. It should be:
bool res = (this->*CaseMethod)( 999, "hello world" );
However, you might find a combination of boost::function and boost::bind makes things a little easier, as you can avoid the bizarre calling syntax.
boost::function<bool(int,std::string)> f=
boost::bind(&MyClass::CaseMethod1,this,_1,_2);
Of course, this will bind it to the current this pointer: you can make the this pointer of the member function an explicit third parameter if you like:
boost::function<bool(MyClass*,int,std::string)> f=
boost::bind(&MyClass::CaseMethod1,_1,_2,_3);
Another alternative might be to use virtual functions and derived classes, but that might require major changes to your code.
You could also build a lookup (if your key range is reasonable) so that you end up writing:
this->*Methods[num]( 999, "hello world" );
This removes the switch as well, and makes the cleanup a bit more worthwhile.
You can certainly do it, although the CaseMethod call isn't correct (it's a pointer to member function, so you have to specify the object on which the method should be called). The correct call would look like this:
bool res = this->*CaseMethod( 999, "hello world" );
On the other hand, I'd recommend boost::mem_fn - you'll have less chances to screw it up. ;)
I don't see the difference between your call and simply calling the method within the switch statement.
No, there is no semantic or readability difference.
The only difference I see is that you are taking a pointer to a method and so forbids to the compiler to inline it or optimizes any call to that method.
Without wider context, it's hard to figure out the right answer, but I sew three possibilities here:
stay with normal switch statement, no need to do anything. This is the most likely solution
use pointers to member function in conjunction with an array, as #Simon says, or may be with a map. For a case statement with a large number of cases, this may be faster.
split t he class into a number of classes, each carrying one function to call, and use virtual functions. This is probably the best solution, buy it will require some serious refatoring. Consider GoF patterns such as State or Visitor or some such.
There's nothing intrinsically wrong with the localised example you've given here, but class method pointers can often be tricky to keep 'safe' if you use them in a wider context, such as outside the class they're a pointer of, or in conjunction with a complex inheritance tree. The way compilers typically manage method pointers is different to 'normal' pointers (since there's extra information beyond just a code entry point), and consequently there are a lot of restrictions on what you can do with them.
If you're just keeping simple pointers the way you describe then you'll be fine, but fore more complex uses you may want to take a look at a more generalised functor system such as boost::bind. These can take pointers to just about any callable code pointer, and can also bind instanced function arguments if necessary.
There are other approaches available, such as using an abstract base class, or specialized template functions.
I'll describe the base class idea.
You can define an abstract base class
class Base { virtual bool Method(int i, const string& s) = 0; };
Then write each of your cases as a subclass, such as
class Case1 : public Base { virtual bool Method(..) { /* implement */; } };
At some point, you will get your "num" variable that indicates which test to execute. You could write a factory function that takes this num (I'll call it which_case), and returns a pointer to Base, and then call Method from that pointer.
Base* CreateBase(int which_num) { /* metacode: return new Case[which_num]; */ }
// ... later, when you want to actually call your method ...
Base* base = CreateBase(23);
base->Method(999, "hello world!");
delete base; // Or use a scoped pointer.
By the way, this application makes me wish C++ supported static virtual functions, or something like "type" as a builtin type - but it doesn't.
Related
I am working on some c Apis and I always have to check some variables are initialized and then clear/destroy/free them using special functions. such as allocation :
ogg_stream_state os;
ogg_stream_init(&os,ogg_page_serialno(&og));
and destroying:
ogg_stream_clear(&os);
I want to call the cleaner function automatically and not explicitly.
Using C++ Templates you can do it easily:
template<typename ARG, typename RET>
class Destroyer
{
public:
typedef RET (*DestoyerFn)(ARG*);
Destroyer(DestoyerFn destroyer_fn, ARG* object_ptr) { objectPointer = object_ptr; destroyerFn = destroyer_fn;}
~Destroyer()
{
if(destroyerFn && objectPointer)
destroyerFn(objectPointer);
}
private:
DestoyerFn destroyerFn;
ARG* objectPointer;
};
ARG is the argument of your cleaner function, and RET is the return type of that (RET needed to avoid compiler warning.)
example call:
Destroyer<ogg_stream_state, int> des_ogg_stream(ogg_stream_clear, &os);
now every where you like, just return from your function, it will call your cleaner function.
In a real-world scenario you most likely want some kind of custom wrapper around the C functions, to encapsulate them and to dodge C like behavior and oddities such as calling convention.
In the real world, I don't believe you can treat any C code as "a generic C API" and design some template class which can handle all possible C APIs. There are far too many things to consider to make such a generic class feasible.
For example, given the following random C code:
//cfile.c
static int* something;
void cfunction_init (void)
{
printf("C function init\n");
something = (int*) malloc(sizeof(*something));
}
void cfunction_cleanup (void)
{
printf("C function cleanup\n");
free(something);
}
You can make a wrapper class like this:
class wrapper
{
public:
wrapper() { cfunction_init(); }
~wrapper() { cfunction_cleanup(); }
};
Then simply declare a wrapper class variable at the appropriate scope:
#include <iostream>
int main()
{
wrapper w;
std::cout << "C++ program executing" << std::endl;
return 0;
}
Program output:
C function init
C++ program executing
C function cleanup
I'd consider wrapping ogg_stream_state with a shared_ptr with custom destructor.
class OggStreamState {
public:
shared_ptr<ogg_stream_state> state;
OggStreamState() :
state(new ogg_stream_state, &ogg_stream_clear)
{}
};
Your code would now look like this:
OggStreamState os;
ogg_stream_init(os.state.get(),ogg_page_serialno(&og));
Which is a little ugly, but this technique gives a logical place to start moving to an object oriented interface rather than a C function based one.
For example you could then move ogg_stream_init into OggStreamState so that it would become
OggStreamState os;
os.init(ogg_page_seialno(&og));
Take it one step further and repeat for the ogg_page, and you'd get
OggPage og = ...;
OggStreamState os;
os.stream_init(og.serialno());
You could even pull the init all the way into the constructor
OggStreamState os(og.serialno());
or at the extreme...
OggStreamState os(og);
Another advantage of this over a pure sentry RAII (like the solution from Lundin) is that you can pass the OggStreamState in and out of functions with out trouble. The compiler will determine when your last reference is destroyed and call the clear function for you. i.e. you can safely have a
OggStreamState oss = function_that_returns_a_stream_state(...);
Of course this technique does introduce other overheads, but usually they are minimal - also it does blur the ownership of the ogg stream slightly, which many or may not be a good thing...
I've started learnig C++ (year ago) mostly because it's univerzal language IMO, and beacause almost everything is possible.
but one thing isn't so:
for example we are writing some code inside an object(class) and we need to find out it's name somehow:
class Test
{
public: const char* getMyIdentiferName()
{
// what now??
}
};
well the best option is to use 'this' keywod but that wouldn't help cos 'this' cant return name?
Test thatsMyName;
const char* = thtsMyName.getMyIdentiferName(); //return string "thatsMyName" how?
how do we get 'thatsMyName' string in in some generic function or even template??
ANOTHER EXAMPLE:(please answer this too)
how do we get typeid of some class?
class MyType
{
public: type_info getType()
{
return typeid(this); //that wont work of course :)
{
};
this looks funny but if any of you have some idea on how to achive similar task...
thanks alot.
EDIT: OK, everybodey say it's impossible to get the name of an object, I found out how to get the name:
class Test
{
public: string getObjectName()
{
string arg = typeid(*this).name();
arg.erase(arg.begin(), arg.begin() + 5);
arg.erase(0,1);
return arg;
}
};
int main()
{
Test thisIsMyName;
cout << thisIsMyName.getObjectName() << endl;
cin.ignore();
return 0;
}
EDIT:
Big thanks to Fiktik answering my second example who found the way oon how to get the type_info of the object!
The first thing you are asking is not possible. At least not directly.
You could create a macro for variable declaration that would register its name somewhere, something like this:
#define CREATE_VARIABLE(type, name) registerVariable<type>(#name); type name
but this is quite cumbersome and cannot be used everywhere. Why would you even want to have this functionality?
The second thing should work with only little adjustments:
class MyType
{
public:
const type_info& getType()
{
return typeid(*this);
}
};
What would you need the variable name for? What you're trying to do is impossible; inside an classes' methods, the name of the variable used for accessing an object isn't known.
Consider this example:
Test * myTest = new Test();
Test * myTest2 = myTest;
const char* identifier = myTest2->getMyIdentifierName();
What should getMyIdentifierName() return? "myTest"? "myTest2"? Nothing at all, since the object was allocated dynamically, and therefore no variable can really claim to "hold" the object?
If you just want to know the variable name which you are currently using for referring to an object, why not just use a string literal for it and pass it wherever you need it? But that doesn't seem to make sense in any real-world application.
If you need a name (i.e., a unique identifier) for an object at runtime, you'll best give the class a member name and initialize that with whatever you need.
Getting the "identifier name" of an object won't work, since there is no unique identifier for an object (other than it's address, to be gotten with &). An unlimited number of references/pointers can designate the same object; at the same time, the language allows objects to be reached by other means than identifiers (v[0] where v is a vector is an object, but not an identifier). This is the case in all programming languages that I know, and I know a dozen of them.
As for your second question, you can return a reference to an std::type_info.
struct Test
{
// pretty useless method
std::type_info const &type() const { return typeid(*this); }
};
int main()
{
Test a;
std::cout << a.type().name() << "\n";
}
My goal is to access a class that is passed in as a parameter inside of myFunction.
Here's what I'm trying to do:
void myFunction(string myString)
{
callFunctionOn(OuterType::InnerType::myString);
}
I'm trying to call some function on something that's in a type. For example, my code in some other file might look like:
namespace OuterType {
namespace InnerType {
//stuff here
}
}
However, using myString in that way doesn't work. If myString holds the value "class1", then I want that callFunctionOn part to be interpreted as
callFunctionOn(OuterType::InnerType::class1);
I feel like this is super simple, but I've been programming all day and my mind grows tired...
SOLVED: It looks like in order to this in this way, I'd need a language with reflection. To solve this I took a different approach to the problem and passed in a pointer to the class instead.
C++ doesn't have reflection built in, but it does have pointers to data, functions, and class members. So you can use a std::map or unordered_set to find the pointer with a particular name (you have to add all the name/pointer pairs into the map beforehand).
Your solution is likely to look something like:
namespace Outer
{
namespace Inner
{
void funcA( void ) { std::cout << "called funcA" << std::endl; }
std::map< std::string, void (*)(void) > members;
}
}
// in some initialization function
Outer::Inner::members["funcA"] = &Outer::Inner::funcA;
// later
std::string myString = "funcA";
void (*f)(void) = Outer::Inner::members[myString]; // lookup function by name
(*f)(); // call function via its pointer
Of course the type of the pointer will probably need to change to meet your application requirements.
You're trying to access a variable based on a run-time string that contains its name? That's not possible; the names of variables disappear after compilation and linking. (Except insofar as they are kept around to facilitate debugging).
Do you mean :
OuterType::InnerType::callFunctionOn(myString);
maybe this idea: operator() can take parameters, wrapping it in a class ine can make calls that are resolved in the overloaded operator() based on its parameters.
template<typename TypeSig, class InstanceOf, typename NA,typename Args>
class FuncMap {
public:
typedef TypeSig (InstanceOf:: *cbMethod) ( NA, Args );
FuncMap( InstanceOf & cInst, cbMethod cbM ) : mcInst(cInst) {mcbM = cbM;}
TypeSig operator() ( NA na, Args args) {return (mcInst.*mcbM)(na, args);}
private:
InstanceOf & mcInst;
cbMethod mcbM;
};
you need to build a map of runtime string values as keys and pointers to instance methods as seen above. i used this for re-dispatch tracing and custom runtime dispatch with lesser than RTTI overhead.
this allows you to have default, if no key found, or other logic as you wish.
I've read through this article, and what I take from it is that when you want to call a pointer to a member function, you need an instance (either a pointer to one or a stack-reference) and call it so:
(instance.*mem_func_ptr)(..)
or
(instance->*mem_func_ptr)(..)
My question is based on this: since you have the instance, why not call the member function directly, like so:
instance.mem_func(..) //or: instance->mem_func(..)
What is the rational/practical use of pointers to member functions?
[edit]
I'm playing with X-development & reached the stage where I am implementing widgets; the event-loop-thread for translating the X-events to my classes & widgets needs to start threads for each widget/window when an event for them arrives; to do this properly I thought I needed function-pointers to the event-handlers in my classes.
Not so: what I did discover was that I could do the same thing in a much clearer & neater way by simply using a virtual base class. No need whatsoever for pointers to member-functions. It was while developing the above that the doubt about the practical usability/meaning of pointers to member-functions arose.
The simple fact that you need a reference to an instance in order to use the member-function-pointer, obsoletes the need for one.
[edit - #sbi & others]
Here is a sample program to illustrate my point:
(Note specifically 'Handle_THREE()')
#include <iostream>
#include <string>
#include <map>
//-----------------------------------------------------------------------------
class Base
{
public:
~Base() {}
virtual void Handler(std::string sItem) = 0;
};
//-----------------------------------------------------------------------------
typedef void (Base::*memfunc)(std::string);
//-----------------------------------------------------------------------------
class Paper : public Base
{
public:
Paper() {}
~Paper() {}
virtual void Handler(std::string sItem) { std::cout << "Handling paper\n"; }
};
//-----------------------------------------------------------------------------
class Wood : public Base
{
public:
Wood() {}
~Wood() {}
virtual void Handler(std::string sItem) { std::cout << "Handling wood\n"; }
};
//-----------------------------------------------------------------------------
class Glass : public Base
{
public:
Glass() {}
~Glass() {}
virtual void Handler(std::string sItem) { std::cout << "Handling glass\n"; }
};
//-----------------------------------------------------------------------------
std::map< std::string, memfunc > handlers;
void AddHandler(std::string sItem, memfunc f) { handlers[sItem] = f; }
//-----------------------------------------------------------------------------
std::map< Base*, memfunc > available_ONE;
void AddAvailable_ONE(Base *p, memfunc f) { available_ONE[p] = f; }
//-----------------------------------------------------------------------------
std::map< std::string, Base* > available_TWO;
void AddAvailable_TWO(std::string sItem, Base *p) { available_TWO[sItem] = p; }
//-----------------------------------------------------------------------------
void Handle_ONE(std::string sItem)
{
memfunc f = handlers[sItem];
if (f)
{
std::map< Base*, memfunc >::iterator it;
Base *inst = NULL;
for (it=available_ONE.begin(); ((it != available_ONE.end()) && (inst==NULL)); it++)
{
if (it->second == f) inst = it->first;
}
if (inst) (inst->*f)(sItem);
else std::cout << "No instance of handler for: " << sItem << "\n";
}
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
void Handle_TWO(std::string sItem)
{
memfunc f = handlers[sItem];
if (f)
{
Base *inst = available_TWO[sItem];
if (inst) (inst->*f)(sItem);
else std::cout << "No instance of handler for: " << sItem << "\n";
}
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
void Handle_THREE(std::string sItem)
{
Base *inst = available_TWO[sItem];
if (inst) inst->Handler(sItem);
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
int main()
{
Paper p;
Wood w;
Glass g;
AddHandler("Paper", (memfunc)(&Paper::Handler));
AddHandler("Wood", (memfunc)(&Wood::Handler));
AddHandler("Glass", (memfunc)(&Glass::Handler));
AddAvailable_ONE(&p, (memfunc)(&Paper::Handler));
AddAvailable_ONE(&g, (memfunc)(&Glass::Handler));
AddAvailable_TWO("Paper", &p);
AddAvailable_TWO("Glass", &g);
std::cout << "\nONE: (bug due to member-function address being relative to instance address)\n";
Handle_ONE("Paper");
Handle_ONE("Wood");
Handle_ONE("Glass");
Handle_ONE("Iron");
std::cout << "\nTWO:\n";
Handle_TWO("Paper");
Handle_TWO("Wood");
Handle_TWO("Glass");
Handle_TWO("Iron");
std::cout << "\nTHREE:\n";
Handle_THREE("Paper");
Handle_THREE("Wood");
Handle_THREE("Glass");
Handle_THREE("Iron");
}
{edit] Potential problem with direct-call in above example:
In Handler_THREE() the name of the method must be hard-coded, forcing changes to be made anywhere that it is used, to apply any change to the method. Using a pointer to member-function the only additional change to be made is where the pointer is created.
[edit] Practical uses gleaned from the answers:
From answer by Chubsdad:
What: A dedicated 'Caller'-function is used to invoke the mem-func-ptr;Benefit: To protect code using function(s) provided by other objectsHow: If the particular function(s) are used in many places and the name and/or parameters change, then you only need to change the name where it is allocated as pointer, and adapt the call in the 'Caller'-function. (If the function is used as instance.function() then it must be changed everywhere.)
From answer by Matthew Flaschen:
What: Local specialization in a classBenefit: Makes the code much clearer,simpler and easier to use and maintainHow: Replaces code that would conventionally be implement using complex logic with (potentially) large switch()/if-then statements with direct pointers to the specialization; fairly similar to the 'Caller'-function above.
The same reason you use any function pointer: You can use arbitrary program logic to set the function pointer variable before calling it. You could use a switch, an if/else, pass it into a function, whatever.
EDIT:
The example in the question does show that you can sometimes use virtual functions as an alternative to pointers to member functions. This shouldn't be surprising, because there are usually multiple approaches in programming.
Here's an example of a case where virtual functions probably don't make sense. Like the code in the OP, this is meant to illustrate, not to be particularly realistic. It shows a class with public test functions. These use internal, private, functions. The internal functions can only be called after a setup, and a teardown must be called afterwards.
#include <iostream>
class MemberDemo;
typedef void (MemberDemo::*MemberDemoPtr)();
class MemberDemo
{
public:
void test1();
void test2();
private:
void test1_internal();
void test2_internal();
void do_with_setup_teardown(MemberDemoPtr p);
};
void MemberDemo::test1()
{
do_with_setup_teardown(&MemberDemo::test1_internal);
}
void MemberDemo::test2()
{
do_with_setup_teardown(&MemberDemo::test2_internal);
}
void MemberDemo::test1_internal()
{
std::cout << "Test1" << std::endl;
}
void MemberDemo::test2_internal()
{
std::cout << "Test2" << std::endl;
}
void MemberDemo::do_with_setup_teardown(MemberDemoPtr mem_ptr)
{
std::cout << "Setup" << std::endl;
(this->*mem_ptr)();
std::cout << "Teardown" << std::endl;
}
int main()
{
MemberDemo m;
m.test1();
m.test2();
}
My question is based on this: since you have the instance, why not call the member function directly[?]
Upfront: In more than 15 years of C++ programming, I have used members pointers maybe twice or thrice. With virtual functions being around, there's not all that much use for it.
You would use them if you want to call a certain member functions on an object (or many objects) and you have to decide which member function to call before you can find out for which object(s) to call it on. Here is an example of someone wanting to do this.
I find the real usefulness of pointers to member functions comes when you look at a higher level construct such as boost::bind(). This will let you wrap a function call as an object that can be bound to a specific object instance later on and then passed around as a copyable object. This is a really powerful idiom that allows for deferred callbacks, delegates and sophisticated predicate operations. See my previous post for some examples:
https://stackoverflow.com/questions/1596139/hidden-features-and-dark-corners-of-stl/1596626#1596626
Member functions, like many function pointers, act as callbacks. You could manage without them by creating some abstract class that calls your method, but this can be a lot of extra work.
One common use is algorithms. In std::for_each, we may want to call a member function of the class of each member of our collection. We also may want to call the member function of our own class on each member of the collection - the latter requires boost::bind to achieve, the former can be done with the STL mem_fun family of classes (if we don't have a collection of shared_ptr, in which case we need to boost::bind in this case too). We could also use a member function as a predicate in certain lookup or sort algorithms. (This removes our need to write a custom class that overloads operator() to call a member of our class, we just pass it in directly to boost::bind).
The other use, as I mentioned, are callbacks, often in event-driven code. When an operation has completed we want a method of our class called to handle the completion. This can often be wrapped into a boost::bind functor. In this case we have to be very careful to manage the lifetime of these objects correctly and their thread-safety (especially as it can be very hard to debug if something goes wrong). Still, it once again can save us from writing large amounts of "wrapper" code.
There are many practical uses. One that comes to my mind is as follows:
Assume a core function such as below (suitably defined myfoo and MFN)
void dosomething(myfoo &m, MFN f){ // m could also be passed by reference to
// const
m.*f();
}
Such a function in the presence of pointer to member functions, becomes open for extension and closed for modification (OCP)
Also refer to Safe bool idiom which smartly uses pointer to members.
The best use of pointers to member functions is to break dependencies.
Good example where pointer to member function is needed is Subscriber/Publisher pattern :
http://en.wikipedia.org/wiki/Publish/subscribe
In my opinion, member function pointers do are not terribly useful to the average programmer in their raw form. OTOH, constructs like ::std::tr1::function that wrap member function pointers together with a pointer to the object they're supposed to operate on are extremely useful.
Of course ::std::tr1::function is very complex. So I will give you a simple example that you wouldn't actually use in practice if you had ::std::tr1::function available:
// Button.hpp
#include <memory>
class Button {
public:
Button(/* stuff */) : hdlr_(0), myhandler_(false) { }
~Button() {
// stuff
if (myhandler_) {
delete hdlr_;
}
}
class PressedHandler {
public:
virtual ~PressedHandler() = 0;
virtual void buttonPushed(Button *button) = 0;
};
// ... lots of stuff
// This stores a pointer to the handler, but will not manage the
// storage. You are responsible for making sure the handler stays
// around as long as the Button object.
void setHandler(const PressedHandler &hdlr) {
hdlr_ = &hdlr;
myhandler_ = false;
}
// This stores a pointer to an object that Button does not manage. You
// are responsible for making sure this object stays around until Button
// goes away.
template <class T>
inline void setHandlerFunc(T &dest, void (T::*pushed)(Button *));
private:
const PressedHandler *hdlr_;
bool myhandler_;
template <class T>
class PressedHandlerT : public Button::PressedHandler {
public:
typedef void (T::*hdlrfuncptr_t)(Button *);
PressedHandlerT(T *ob, hdlrfuncptr_t hdlr) : ob_(ob), func_(hdlr) { }
virtual ~PressedHandlerT() {}
virtual void buttonPushed(Button *button) { (ob_->*func_)(button); }
private:
T * const ob_;
const hdlrfuncptr_t func_;
};
};
template <class T>
inline void Button::setHandlerFunc(T &dest, void (T::*pushed)(Button *))
{
PressedHandler *newhandler = new PressedHandlerT<T>(&dest, pushed);
if (myhandler_) {
delete hdlr_;
}
hdlr_ = newhandler;
myhandler_ = true;
}
// UseButton.cpp
#include "Button.hpp"
#include <memory>
class NoiseMaker {
public:
NoiseMaker();
void squee(Button *b);
void hiss(Button *b);
void boo(Button *b);
private:
typedef ::std::auto_ptr<Button> buttonptr_t;
const buttonptr_t squeebutton_, hissbutton_, boobutton_;
};
NoiseMaker::NoiseMaker()
: squeebutton_(new Button), hissbutton_(new Button), boobutton_(new Button)
{
squeebutton_->setHandlerFunc(*this, &NoiseMaker::squee);
hissbutton_->setHandlerFunc(*this, &NoiseMaker::hiss);
boobutton_->setHandlerFunc(*this, &NoiseMaker::boo);
}
Assuming Button is in a library and not alterable by you, I would enjoy seeing you implement that cleanly using a virtual base class without resorting to a switch or if else if construct somewhere.
The whole point of pointers of pointer-to-member function type is that they act as a run-time way to reference a specific method. When you use the "usual" syntax for method access
object.method();
pointer->method();
the method part is a fixed, compile-time specification of the method you want to call. It is hardcoded into your program. It can never change. But by using a pointer of pointer-to-member function type you can replace that fixed part with a variable, changeable at run-time specification of the method.
To better illustrate this, let me make the following simple analogy. Let's say you have an array
int a[100];
You can access its elements with fixed compile-time index
a[5]; a[8]; a[23];
In this case the specific indices are hardcoded into your program. But you can also access array's elements with a run-time index - an integer variable i
a[i];
the value of i is not fixed, it can change at run-time, thus allowing you to select different elements of the array at run-time. That is very similar to what pointers of pointer-to-member function type let you do.
The question you are asking ("since you have the instance, why not call the member function directly") can be translated into this array context. You are basically asking: "Why do we need a variable index access a[i], when we have direct compile-time constant access like a[1] and a[3]?" I hope you know the answer to this question and realize the value of run-time selection of specific array element.
The same applies to pointers of pointer-to-member function type: they, again, let you to perform run-time selection of a specific class method.
The use case is that you have several member methods with the same signature, and you want to build logic which one should be called under given circumstances. This can be helpful to implement state machine algorithms.
Not something you use everyday...
Imagine for a second you have a function that could call one of several different functions depending on parameters passed.
You could use a giant if/else if statement
You could use a switch statement
Or you could use a table of function pointers (a jump table)
If you have a lot of different options the jump table can be a much cleaner way of arranging your code ...
Its down to personal preference though. Switch statement and jump table correspond to more or less the same compiled code anyway :)
Member pointers + templates = pure win.
e.g. How to tell if class contains a certain member function in compile time
or
template<typename TContainer,
typename TProperty,
typename TElement = decltype(*Container().begin())>
TProperty grand_total(TContainer& items, TProperty (TElement::*property)() const)
{
TProperty accum = 0;
for( auto it = items.begin(), end = items.end(); it != end; ++it) {
accum += (it->*property)();
}
return accum;
}
auto ship_count = grand_total(invoice->lineItems, &LineItem::get_quantity);
auto sub_total = grand_total(invoice->lineItems, &LineItem::get_extended_total);
auto sales_tax = grand_total(invoice->lineItems, &LineItem::calculate_tax);
To invoke it, you need a reference to an instance, but then you can call the func direct & don't need a pointer to it.
This is completely missing the point. There are two indepedent concerns here:
what action to take at some later point in time
what object to perform that action on
Having a reference to an instance satisfies the second requirement. Pointers to member functions address the first: they are a very direct way to record - at one point in a program's execution - which action should be taken at some later stage of execution, possibly by another part of the program.
EXAMPLE
Say you have a monkey that can kiss people or tickle them. At 6pm, your program should set the monkey loose, and knows whom the monkey should visit, but around 3pm your user will type in which action should be taken.
A beginner's approach
So, at 3pm you could set a variable "enum Action { Kiss, Tickle } action;", then at 6pm you could do something like "if (action == Kiss) monkey->kiss(person); else monkey->tickle(person)".
Issues
But that introducing an extra level of encoding (the Action type's introduced to support this - built in types could be used but would be more error prone and less inherently meaningful). Then - after having worked out what action should be taken at 3pm, at 6pm you have to redundantly consult that encoded value to decide which action to take, which will require another if/else or switch upon the encoded value. It's all clumsy, verbose, slow and error prone.
Member function pointers
A better way is to use a more specialised varibale - a member function pointer - that directly records which action to perform at 6pm. That's what a member function pointer is. It's a kiss-or-tickle selector that's set earlier, creating a "state" for the monkey - is it a tickler or a kisser - which can be used later. The later code just invokes whatever function's been set without having to think about the possibilities or have any if/else-if or switch statements.
To invoke it, you need a reference to an instance, but then you can call the func direct & don't need a pointer to it.
Back to this. So, this is good if you make the decision about which action to take at compile time (i.e. a point X in your program, it'll definitely be a tickle). Function pointers are for when you're not sure, and want to decouple the setting of actions from the invocation of those actions.
I'm lead dev for Bitfighter, and we're working with a mix of Lua and C++, using Lunar (a variant of Luna, available here) to bind them together.
I know this environment does not have good support for object orientation and inheritance, but I'd like to find some way to at least partially work around these limitations.
Here's what I have:
C++ Class Structure
GameItem
|---- Rock
|---- Stone
|---- RockyStone
Robot
Robot implements a method called getFiringSolution(GameItem item) that looks at the position and speed of item, and returns the angle at which the robot would need to fire to hit item.
-- This is in Lua
angle = robot:getFiringSolution(rock)
if(angle != nil) then
robot:fire(angle)
end
So my problem is that I want to pass rocks, stones, or rockyStones to the getFiringSolution method, and I'm not sure how to do it.
This works for Rocks only:
// C++ code
S32 Robot::getFiringSolution(lua_State *L)
{
Rock *target = Lunar<Rock>::check(L, 1);
return returnFloat(L, getFireAngle(target)); // returnFloat() is my func
}
Ideally, what I want to do is something like this:
// This is C++, doesn't work
S32 Robot::getFiringSolution(lua_State *L)
{
GameItem *target = Lunar<GameItem>::check(L, 1);
return returnFloat(L, getFireAngle(target));
}
This potential solution does not work because Lunar's check function wants the object on the stack to have a className that matches that defined for GameItem. (For each object type you register with Lunar, you provide a name in the form of a string which Lunar uses to ensure that objects are of the correct type.)
I would settle for something like this, where I have to check every possible subclass:
// Also C++, also doesn't work
S32 Robot::getFiringSolution(lua_State *L)
{
GameItem *target = Lunar<Rock>::check(L, 1);
if(!target)
target = Lunar<Stone>::check(L, 1);
if(!target)
target = Lunar<RockyStone>::check(L, 1);
return returnFloat(L, getFireAngle(target));
}
The problem with this solution is that the check function generates an error if the item on the stack is not of the correct type, and, I believe, removes the object of interest from the stack so I only have one attempt to grab it.
I'm thinking I need to get a pointer to the Rock/Stone/RockyStone object from the stack, figure out what type it is, then cast it to the correct thing before working with it.
The key bit of Lunar which does the type checking is this:
// from Lunar.h
// get userdata from Lua stack and return pointer to T object
static T *check(lua_State *L, int narg) {
userdataType *ud =
static_cast<userdataType*>(luaL_checkudata(L, narg, T::className));
if(!ud) luaL_typerror(L, narg, T::className);
return ud->pT; // pointer to T object
}
If I call it thusly:
GameItem *target = Lunar<Rock>::check(L, 1);
then the luaL_checkudata() checks to see if the item on the stack is a Rock. If so, everything is peachy, and it returns a pointer to my Rock object, which gets passed back to the getFiringSolution() method. If there is a non-Rock item on the stack, the cast returns null, and luaL_typerror() gets called, which sends the app off into lala land (where the error handling prints a diagnostic and terminates the robot with extreme prejudice).
Any ideas on how to move forward with this?
Many thanks!!
Best solution I've come up with... ugly, but works
Based on the suggestions below, I came up with this:
template <class T>
T *checkItem(lua_State *L)
{
luaL_getmetatable(L, T::className);
if(lua_rawequal(L, -1, -2)) // Lua object on stack is of class <T>
{
lua_pop(L, 2); // Remove both metatables
return Lunar<T>::check(L, 1); // Return our object
}
else // Object on stack is something else
{
lua_pop(L, 1); // Remove <T>'s metatable, leave the other in place
// for further comparison
return NULL;
}
}
Then, later...
S32 Robot::getFiringSolution(lua_State *L)
{
GameItem *target;
lua_getmetatable(L, 1); // Get metatable for first item on the stack
target = checkItem<Rock>(L);
if(!target)
target = checkItem<Stone>(L);
if(!target)
target = checkItem<RockyStone>(L);
if(!target) // Ultimately failed to figure out what this object is.
{
lua_pop(L, 1); // Clean up
luaL_typerror(L, 1, "GameItem"); // Raise an error
return returnNil(L); // Return nil, but I don't think this
// statement will ever get run
}
return returnFloat(L, getFireAngle(target));
}
There are probably further optimizations I can do with this... I'd really like to figure out how to collapse this into a loop because, in reality, I will have a lot more than three classes to deal with, and this process is a bit cumbersome.
Slight improvement on the above solution
C++:
GameItem *LuaObject::getItem(lua_State *L, S32 index, U32 type)
{
switch(type)
{
case RockType:
return Lunar<Rock>::check(L, index);
case StoneType:
return Lunar<Stone>::check(L, index);
case RockyStoneType:
return Lunar<RockyStone>::check(L, index);
default:
displayError();
}
}
Then, later...
S32 Robot::getFiringSolution(lua_State *L)
{
S32 type = getInteger(L, 1); // My fn to pop int from stack
GameItem *target = getItem(L, 2, type);
return returnFloat(L, getFireAngle(target)); // My fn to push float to stack
}
Lua helper function, included as a separate file to avoid user needing to add this manually to their code:
function getFiringSolution( item )
type = item:getClassID() -- Returns an integer id unique to each class
if( type == nil ) then
return nil
end
return bot:getFiringSolution( type, item )
end
User calls this way from Lua:
angle = getFiringSolution( item )
I think you're trying to do the method dispatch in the wrong place. (This problem is symptomatic of a difficulty with all of these "automated" ways of making Lua interact with C or C++: with each of them, there's some magic going on behind the scenes, and it's not always obvious how to make it work. I don't understand why more people don't just use Lua's C API.)
I had a look at the Lunar web pages, and it looks to me as if you need to create a methods table on type T and then call the Luna<T>::Register method. There's a simple example on the web. If I'm reading the code correctly, none of the glue code in your question is actually the recommended way of doing things with Lunar. (I'm also assuming that you can implement these methods entirely as C++ calls.)
This is all pretty dodgy because the documentation on Lunar is thin.
A sensible alternative would be to do all the work yourself, and just associate each C++ type with a Lua table containing its methods. Then you have the Lua __index metamethod consult that table, and Bob's your uncle. Lunar is doing something close to these, but it's sufficiently dressed up with C++ templates that other goo that I'm not sure how to make it work.
The template stuff is very clever. You might want either to take the time to understand deeply how it works, or to reconsider if and how you want to use it.
Summary: for each class, make an explicit methods table, and register each class using the Lunar Register method. Or roll your own.
You should tell us what exactly does not work in your code. I suppose that it is Lunar<Rock>::check(L, 1) that fails for all non-Rocks. Am I correct?
Also it would be fine if you specified which version of Lunar you use (a link to it would be great).
If it is this one, then class type is stored in the Lua object metatable (one may say that this metatable is the type).
Looks like the simplest way to check if object is a Rock without patching Lunar is to call luaL_getmetatable(L, Rock::className) to get class metatable and to compare it with lua_getmetatable(L, 1) of your first argument (note luaL in the first function name). This is a bit hackish, but should work.
If you fine with patching Lunar, one of possible ways is to add some __lunarClassName field to the metatable and store T::name there. Provide lunar_typename() C++ function (outside of the Lunar template class -- as we do not need T there) then, and return from it the value of that __lunarClassName field of argument's metatable. (Do not forget to check if object has metatable and that metatable has such field.) You may check Lua object type by calling lunar_typename() then.
A bit of advice from personal experience: the more of business logic you push to Lua, the better. Unless you're pressed by severe performance constraints, you probably should consider to move all that hierarchy to Lua -- your life would become much simpler.
If I may help you further, please say so.
Update: The solution you've updated your post with, looks correct.
To do the metatable-based dispatch in C, you may use, for example, a map of integral lua_topointer() value of the luaL_getmetatable() for a type to a function object/pointer which knows how to deal with that type.
But, again, I suggest to move this part to Lua instead. For example: Export type-specific functions getFiringSolutionForRock(), getFiringSolutionForStone() and getFiringSolutionForRockyStone() from C++ to Lua. In Lua, store table of methods by metatable:
dispatch =
{
[Rock] = Robot.getFiringSolutionForRock;
[Stone] = Robot.getFiringSolutionForStone;
[RockyStone] = Robot.getFiringSolutionForRockyStone;
}
If I'm right, the next line should call the correct specialized method of robot object.
dispatch[getmetatable(rock)](robot, rock)
I suggest that you define an object oriented system in pure lua, and then write a custom binding to C++ for that aspect of the API.
Lua is well suited for prototype OO implementations, where tables are used for emulating classes, in which one entry has a function called new, which when called returns an appropriate table of the same 'type'.
From C++, however, make a LuaClass that has a .invoke method, accepting a C string (ie, a null-terminated const char array) to specify the name of the member function you want to call, and depending on how you want to handle variable arguments, have several templated versions of this .invoke method for zero, one, two, ... N arguments as neccessary, or define a method of passing a variable number of arguments into it, and there are many ways to do that.
For Lua, I suggest making two .invoke methods, one which expects an std::vector, and another that expects an std::map, but I'll leave that up to you. :)
In my last Lua/C++ project, I used only null-terminated arrays of C-strings, requiring lua to convert the string to an appropriate value.
Enjoy.
I was facing quite the same needs, and here is what I came up with.
(I had to do some minor changes to the Lunar header)
First, I've added a global "interface" for all the classes that will contains Lua methods.
I understand this could appear less flexible than the "original" way, but in my opinion it's clearer, and I do need it to perform dynamic casts.
class LuaInterface
{
public:
virtual const char* getClassName() const=0;
};
Yes, it only contains one pure virtual method, which will obviously return the static "className" attribute in the derived classes. That way, you can have polymorphism, with keeping this static name member needed by the templated lunar classes.
To make my life easier, I've also added some defines :
#define LuaClass(T) private: friend class Lunar<T>; static const char className[]; static Lunar<T>::RegType methods[]; public: const char* getClassName() const { return className; }
So you basically just have to declare a class like this :
class MyLuaClass: public LuaInterface
{
LuaClass(MyLuaClass)
public:
MyLuaMethod(lua_State* L);
};
Nothing particular here.
I also need a "singleton" (ouch, I know : it doesn't really have to be a singleton just do whatever you feel like to)
class LuaAdapter
{
//SINGLETON part : irrelevant
public:
const lua_State* getState() const { return _state; }
lua_State* getState() { return _state; }
template <class T>
void registerClass(const std::string &name)
{
Lunar<T>::Register(_state);
_registeredClasses.push_back(name);
}
void registerFunction(const std::string &name, lua_CFunction f)
{
lua_register(_state, name.c_str(), f);
_registeredFunctions.push_back(name);
}
bool loadScriptFromFile(const std::string &script);
bool loadScript(const std::string &script);
const StringList& getRegisteredClasses() const { return _registeredClasses; }
const StringList& getRegisteredFunctions() const { return _registeredFunctions; }
LuaInterface* getStackObject() const;
private:
lua_State* _state;
StringList _registeredClasses;
StringList _registeredFunctions;
};
For now, just look at the registerClass method : we store its name here in a StringList (just a list of string)
Now, the idea is to implement a proxy to register our classes :
template<class _Type>
class RegisterLuaClassProxy
{
public:
RegisterLuaClassProxy(const std::string &name)
{
LuaAdapter::instance()->registerClass<_Type>(name);
}
~RegisterLuaClassProxy()
{
}
};
We need to build one instance of each proxy for each LuaInterface class.
ie: in MyClass.cpp, after the standard "Lunar" method declaration :
RegisterLuaClass(MyClass)
With, again, a couple of defines :
#define RegisterLuaClassWithName(T, name) const char T::className[] = name; RegisterLuaClassProxy<T> T ## _Proxy(name);
#define RegisterLuaClass(T) RegisterLuaClassWithName(T, #T)
Do the same with the "functions" methods/proxy.
Now some little changes in the Lunar header :
remove the "userdataType" structure from the class, and define a single struct outside the class :
typedef struct { LuaInterface *pT; } userdataType;
(note that you will also need to add some static_cast inside the Lunar class)
Well, well. Now we have all the structures we need to perform our operation, I've defined it in the getStackObject() method of my LuaAdapter, based on your code.
LuaInterface* LuaAdapter::getStackObject() const
{
lua_getmetatable(_state, 1);
for(StringList::const_iterator it = _registeredClasses.begin(); it != _registeredClasses.end(); ++it)
{
// CHECK ITEM
luaL_getmetatable(_state, it->c_str());
if(lua_rawequal(_state, -1, -2)) // Lua object on stack is of class <T>
{
lua_pop(_state, 2); // Remove both metatables
userdataType *ud = static_cast<userdataType*>(luaL_checkudata(_state, 1, it->c_str()));
if(!ud) luaL_typerror(_state, 1, it->c_str());
return ud->pT;
}
else // Object on stack is something else
{
// Remove <T>'s metatable, leave the other in place for further comparison
lua_pop(_state, 1);
}
}
return NULL;
}
Here is the trick : since the returned pointer points to an abstract class, you can safely use dynamic_cast<> with it. And add some "intermediate" abstract classes, with nice virtual methods, like :
int fire(lua_State *L)
{
GameItem *item = dynamic_cast<GameItem*>(LuaAdapter::instance()->getStackObject());
if( item!= NULL)
{
item->fire();
}
return 0;
}
... I Hope this will help. Don't hesitate to correct me / add stuff / feedback.
Cheers :)