Choosing a member function based on a string - c++

I have a set of hardware handler classes, all derived from a base class, which have to respond to an incoming data packet. Part of this packet is an ASCII string, which determined which member function of the hardware handler is used to process the packet (for example "fan" would execute the ToggleFan() function.
class HardwareHandler {
virtual void dispatchCommand(const String& cmd) = 0;
}
class FooblerHandler : public HardwareHandler {
void toogleFan();
void dispatchCommand(const String& cmd) {
//is this a "good" way to do this?
if (cmd == "fan")
toggleFan();
}
}
I am using JUCE as a framework, which means I have things like templated HashMaps and String.
However, I'm having trouble coming up with a tidy way of selecting the right handler function based on this string. The construct
if (str == "hello")
FooCommand();
else if (str == "bar")
BarCommand();
looks pretty ugly to me conceptually as there are a lot of relatively expensive string comparisons in there. However, the code is easy to write and the logic is kept in a single place per class.
Another alternative I have tried is to make a hash-map of the strings to an enum and use that a the switch statement:
switch (str.getHash())
{
case CmdFoo:
FooCommnad();
break;
....and so on
}
However this also requires me to set up a static hash-map, as well as maintain the switch to match.
Something else I tried is a hash-map form the string to the member function pointer itself, hoping to be able to jump directly from the string to the member function without having list them in a case statement, and also allows a very generic dispatch function, as it just needs to look up in the hash-map, it doesn't even need to know all the options - they can be contained solely in the hash-map, allowing me to maybe push the dispatch function into the base handler class and not repeat myself in each specific device handler. However, this method has stumped me as I can't quite work out how to do it correctly, or even if it is possible to do this with a static hash-map and member-functions.
Is there an idiomatic way to dispatch to member functions based on a string (or similar hard-to-compare type), preferably with as much logic able to be genericised and moved to the parent class as possible?

Here is my try. You can encapsulate the mapping mechanism into a class:
#include <iostream>
#include <string>
#include <functional>
#include <map>
class X;
template<class X>
class handler_factory;
template<>
class handler_factory<X>
{
private:
using HandlerType = void (X::*)();
public:
handler_factory();
HandlerType get(const std::string& name) const
{
if (handlers.find(name) == handlers.end())
return nullptr;
else
return (*handlers.find(name)).second;
}
private:
std::map<std::string, HandlerType> handlers;
};
class X
{
public:
friend class handler_factory<X>;
private:
void f();
void h();
};
handler_factory<X>::handler_factory()
{
handlers["f"] = &X::f;
handlers["h"] = &X::h;
}
void X::f() { std::cout << "X::f();"; }
void X::h() { std::cout << "X::h();"; }
And your dispatch method can be implemented as:
void dispatch_method(const std::string& name)
{
if (find_handler(name))
(this->*find_handler(name))();
}
int main()
{
X().dispatch_method("f");
}
Where find_handler is defined as a private helper method:
private:
auto find_handler(const std::string& name)
-> decltype(handler_factory<X>().get(name))
{
return handler_factory<X>().get(name);
}

I think the most efficient way to deal with the problem is creating a std::map that would map your strings into appropriate functions. The method is fast (due to the logarithmic searching algorithm), easy and safe.
class FooblerHandler : public HardwareHandler {
typedef void (HardwareHandler::*function)();
map<string,function> commandMap;
void dispatchCommand(const string& cmd) {
if(commandMap.count(cmd))
(this->*commandMap.find(cmd)->second)();
else
cout << "No command found with name \"" <<cmd<< "\"." << endl;
}
};
And of course you should init the map inside the constructor (or somewhere before using it):
commandMap["fan"] = &FooblerHandler::toogleFan;
commandMap["someOtherCommand"] = &FooblerHandler::otherFunction;
Maps and included in the Standard Template Library (STL) which nearly all IDE's supply.
EDIT:
I didn't quite read the text at the end. Well - now you know the syntax :)

Related

How to hold a List<> of opaque handles in CLI/C++?

I am writing a CLI/C++ wrapper for a C-library in order to use it in C#. It must be said, I only have access to the C header file and the .lib of the C-library, not the source code.
Some of the functions I am trying to wrap are returning opaque handles, such as:
typedef struct SanEvent_s *SanEvent;
typedef struct SanValue_s *SanValue;
Returning objects of this type on the C# end seems like trouble to me, as I don't know the implementation of the struct (I tried returning the SanEvent type in the C++ wrapper but on the C# end that type is not accessible due to "protection level" or whatever it said). My plan at the moment is therefore to write some helper functions, which instead just return an integer which represents an, for example, San Event in a list or something. The list would be kept in the managed C++ wrapper, where I can actually manage the San Event type.
My problem is, I don't really know how to do this with this type of type.
This:
using System::Collections::Generic::List;
namespace Wrapper {
public ref class Analytics
{
private:
static List<SanEvent^>^ events = gcnew List<SanEvent^>();
}
}
Gives me the errors: handle to handle, pointer, or reference is not allowed
The right hand side also complains about expected type specifier + the same error as above.
Can anyone give me some tips on how I could tackle this issue neatly and efficiently? My List implementation is not carved in stone, and I am open to better suggestions.
Let's imagine following SanEvent declaration
struct SanEvent_s
{
int test;
};
typedef SanEvent_s *SanEvent;
And following C++ API to work with such event:
SanEvent GetEvent()
{
auto e = new SanEvent_s();
e->test=42;
return e;
}
int UseEvent(SanEvent pEvent)
{
return pEvent->test;
}
All this code contained in static library project (fully native, no CLR).
Then we have C++/CLI project to wrap this static lib.
Here we have wrapper for event itself:
#include "./../CppLib/SanEvent_s.h"
public ref class SanEventWrapper: Microsoft::Win32::SafeHandles::SafeHandleZeroOrMinusOneIsInvalid
{
public:
static SanEventWrapper^ GetWrapper()
{
return gcnew SanEventWrapper(GetEvent());
}
internal:
SanEventWrapper(SanEvent event):SafeHandleZeroOrMinusOneIsInvalid(true)
{
this->e = event;
this->handle = System::IntPtr(event);
}
int UseWrapper()
{
return ::UseEvent(this->e);
}
protected:
bool ReleaseHandle() override
{
//todo: release wrapped event
return true;
}
private:
SanEvent e;
};
And another class which uses such a wrapper
public ref class SanEventConsumer
{
public:
int ConsumeEvent(SanEventWrapper^ wrapper)
{
return wrapper->UseWrapper();
}
};
And finally, how to use all this from C#:
var wrapper = SanEventWrapper.GetWrapper();
var consumer = new SanEventConsumer();
var res = consumer.ConsumeEvent(wrapper);
Console.WriteLine(res);
This should print 42;
Notes:
Notes:
this is a very simplified sample. It should be adapted ytrin accordance with semantics of 'SanEvent' struct as well as with respect of requirements of SafeHandle documentation (https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.safehandle?view=netframework-4.8 and https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.safehandles.safehandlezeroorminusoneisinvalid?view=netframework-4.8)
you should decide if your wrapper will own the SunEvent object or not and implement ReleaseHandle and Dispose accordingly to this.
you may consider to use another base class from this list https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.safehandles?view=netframework-4.8 instead of 'SafeHandleZeroOrMinusOneIsInvalid' or even make direct inhernitance from SafeHandle.
you can even think about dropping SafeHandle-related stuff at all and making the simple wrapper by your own, but it can give some surprises in connection with GC.
depending of the semantics of the SunEvent you may be also need to implement factory to guarantee that you always return to the managed code the same instance of wrapper for all equals values of raw native pointer.
Here's something similar to what #Serg has above, but explicitly goes with the idea that you have NO IDEA in the C# world what's inside the object.
So if you have a C++/CLI library made in VS, you get this in the .h file:
#pragma once
#include <cstdint>
using namespace System;
namespace CppCliLibrary {
public ref class Class1
{
public:
static IntPtr getOpaqueInstance(int32_t argument);
static void useOpaqueInstance(IntPtr obj);
static void freeOpaqueInstance(IntPtr obj);
};
}
Like above, using IntPtr to represent a pointer to "whatever". The corresponding .cpp file is this:
#include "pch.h"
#include "CppCliLibrary.h"
#include <string>
#include <iostream>
namespace CppCliLibrary
{
class OpaqueCppClass
{
public:
OpaqueCppClass(int32_t arg)
: m_int(arg) { }
int32_t m_int;
};
}
IntPtr CppCliLibrary::Class1::getOpaqueInstance(int32_t argument)
{
return IntPtr(new OpaqueCppClass(argument));
}
void CppCliLibrary::Class1::useOpaqueInstance(IntPtr obj)
{
CppCliLibrary::OpaqueCppClass* deref = reinterpret_cast<CppCliLibrary::OpaqueCppClass *>(obj.ToPointer());
std::cout << "Contents of class are: " << deref->m_int << std::endl;
}
void CppCliLibrary::Class1::freeOpaqueInstance(IntPtr obj)
{
CppCliLibrary::OpaqueCppClass* deref = reinterpret_cast<CppCliLibrary::OpaqueCppClass*>(obj.ToPointer());
std::cout << "Deleting class with contents: " << deref->m_int << std::endl;
delete deref;
}
Then in the C# file you have this:
namespace CsCoreConsole
{
class Program
{
static void Main(string[] args)
{
// Get an instance
var instance = CppCliLibrary.Class1.getOpaqueInstance(52);
// Use it
Console.WriteLine("Got an instance we're using");
CppCliLibrary.Class1.useOpaqueInstance(instance);
Console.WriteLine("Freeing it");
CppCliLibrary.Class1.freeOpaqueInstance(instance);
// Add a bunch to a list
List<IntPtr> opaqueInstances = new List<IntPtr>();
for(int i = 0; i < 5; i++)
{
opaqueInstances.Add(CppCliLibrary.Class1.getOpaqueInstance(i * 10));
}
// Use them all
foreach(var cur in opaqueInstances)
{
CppCliLibrary.Class1.useOpaqueInstance(cur);
}
// Delete them all
foreach (var cur in opaqueInstances)
{
CppCliLibrary.Class1.freeOpaqueInstance(cur);
}
}
}
}
Of course the C# project needs to reference the C++/CLI one, but you get the idea here. The C++/CLI is a factory (nothing more, nothing less) for IntPtr and it can use it as well, because to C# it's opaque. C# knows of nothing more than IntPtr.
The idea from Serg is to wrap it more, in a type-safe way. Sure, that can work, but this is the "even more raw" variant, if you want to put it "directly" into a List<>

C++ code generation: create a factory for function pointers

I have a long and steadily growing list of (non-member) functions and I need to select one of the functions from this list at runtime (based on a command line argument). At the moment I do this using a factory function which takes a string (the name of the function) and returns a pointer to the function. However this means I have to edit the factory function every time I add a new function (which is both annoying and a violation of the DRY principle).
I would like to somehow generate the factory function by parsing the source code of the list of functions (inspired by reading the code generation section of The Pragmatic Programmer last night). However it seems that it is very hard to parse C++ correctly and I would rather not make my project depend on libclang just for this.
So my question is: how can I select a function by name at runtime without introducing heavyweight dependencies?
Is it "safe" to only partially parse the c++ code (e.g. just using a regex to extract function names by matching something that looks like a set of function arguments)?
Are there any other (portable and not too hacky) ways of doing this without manually writing the selection code?
edit: Forgot to say: I'm not allowed to use C++11, so no lambda functions unfortunately.
Here is a fully working example :
#include <iostream>
#include <map>
namespace detail {
struct FuncPtrMap {
friend struct FuncPtrRegisterer;
using FuncPtr = void(*)();
static std::map<std::string, FuncPtr> const &getMap() {
return getWritableMap();
}
private:
// SIOF-proof singleton
static std::map<std::string, FuncPtr> &getWritableMap() {
static std::map<std::string, FuncPtr> theMap;
return theMap;
}
};
// Each static instance will register one function pointer
struct FuncPtrRegisterer {
FuncPtrRegisterer(FuncPtrMap::FuncPtr funcPtr, char const *funcName) {
FuncPtrMap::getWritableMap().emplace(funcName, funcPtr);
}
};
}
// Public access to the function pointers map
auto const &gFunctionPointersMap = detail::FuncPtrMap::getMap();
#define DO_CAT(A, B) A##B
#define CAT(A, B) DO_CAT(A, B)
// Registering macro : defines a static registerer
// with a (hopefully) unique name.
#define REGISTER_FUNC(NAME) detail::FuncPtrRegisterer \
CAT(fpreg, __COUNTER__) (&NAME, #NAME)
//
// Test
//
void myFunc1() {
std::cout << "func1\n";
}
REGISTER_FUNC(myFunc1);
void myFunc2() {
std::cout << "func2\n";
}
REGISTER_FUNC(myFunc2);
int main()
{
for(auto const &kv : gFunctionPointersMap) {
std::cout << "Calling " << kv.first << " : ";
kv.second();
}
return 0;
}
Prints :
Calling myFunc1 : func1
Calling myFunc2 : func2
Just put a REGISTER_FUNC(func) after each function you wish to register. You only need the declaration of the function, not its definition. Beware that this will not work in header files though.
Afterwards, you can access gFunctionPointersMap at any time from the very start of main :)
Edit : C++03 version here (nothing much changes really).

Trying to avoid repetitively call a function

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.

What is the practical use of pointers to member functions?

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.

How can I keep track of (enumerate) all classes that implement an interface

I have a situation where I have an interface that defines how a certain class behaves in order to fill a certain role in my program, but at this point in time I'm not 100% sure how many classes I will write to fill that role. However, at the same time, I know that I want the user to be able to select, from a GUI combo/list box, which concrete class implementing the interface that they want to use to fill a certain role. I want the GUI to be able to enumerate all available classes, but I would prefer not to have to go back and change old code whenever I decide to implement a new class to fill that role (which may be months from now)
Some things I've considered:
using an enumeration
Pros:
I know how to do it
Cons
I will have to update update the enumeration when I add a new class
ugly to iterate through
using some kind of static list object in the interface, and adding a new element from within the definition file of the implementing class
Pros:
Wont have to change old code
Cons:
Not even sure if this is possible
Not sure what kind of information to store so that a factory method can choose the proper constructor ( maybe a map between a string and a function pointer that returns a pointer to an object of the interface )
I'm guessing this is a problem (or similar to a problem) that more experienced programmers have probably come across before (and often), and there is probably a common solution to this kind of problem, which is almost certainly better than anything I'm capable of coming up with. So, how do I do it?
(P.S. I searched, but all I found was this, and it's not the same: How do I enumerate all items that implement a generic interface?. It appears he already knows how to solve the problem I'm trying to figure out.)
Edit: I renamed the title to "How can I keep track of... " rather than just "How can I enumerate..." because the original question sounded like I was more interested in examining the runtime environment, where as what I'm really interested in is compile-time book-keeping.
Create a singleton where you can register your classes with a pointer to a creator function.
In the cpp files of the concrete classes you register each class.
Something like this:
class Interface;
typedef boost::function<Interface* ()> Creator;
class InterfaceRegistration
{
typedef map<string, Creator> CreatorMap;
public:
InterfaceRegistration& instance() {
static InterfaceRegistration interfaceRegistration;
return interfaceRegistration;
}
bool registerInterface( const string& name, Creator creator )
{
return (m_interfaces[name] = creator);
}
list<string> names() const
{
list<string> nameList;
transform(
m_interfaces.begin(), m_interfaces.end(),
back_inserter(nameList)
select1st<CreatorMap>::value_type>() );
}
Interface* create(cosnt string& name ) const
{
const CreatorMap::const_iterator it
= m_interfaces.find(name);
if( it!=m_interfaces.end() && (*it) )
{
return (*it)();
}
// throw exception ...
return 0;
}
private:
CreatorMap m_interfaces;
};
// in your concrete classes cpp files
namespace {
bool registerClassX = InterfaceRegistration::instance("ClassX", boost::lambda::new_ptr<ClassX>() );
}
ClassX::ClassX() : Interface()
{
//....
}
// in your concrete class Y cpp files
namespace {
bool registerClassY = InterfaceRegistration::instance("ClassY", boost::lambda::new_ptr<ClassY>() );
}
ClassY::ClassY() : Interface()
{
//....
}
I vaguely remember doing something similar to this many years ago. Your option (2) is pretty much what I did. In that case it was a std::map of std::string to std::typeinfo. In each, .cpp file I registered the class like this:
static dummy = registerClass (typeid (MyNewClass));
registerClass takes a type_info object and simply returns true. You have to initialize a variable to ensure that registerClass is called during startup time. Simply calling registerClass in the global namespace is an error. And making dummy static allow you to reuse the name across compilation units without a name collision.
I referred to this article to implement a self-registering class factory similar to the one described in TimW's answer, but it has the nice trick of using a templated factory proxy class to handle the object registration. Well worth a look :)
Self-Registering Objects in C++ -> http://www.ddj.com/184410633
Edit
Here's the test app I did (tidied up a little ;):
object_factory.h
#include <string>
#include <vector>
// Forward declare the base object class
class Object;
// Interface that the factory uses to communicate with the object proxies
class IObjectProxy {
public:
virtual Object* CreateObject() = 0;
virtual std::string GetObjectInfo() = 0;
};
// Object factory, retrieves object info from the global proxy objects
class ObjectFactory {
public:
static ObjectFactory& Instance() {
static ObjectFactory instance;
return instance;
}
// proxies add themselves to the factory here
void AddObject(IObjectProxy* object) {
objects_.push_back(object);
}
size_t NumberOfObjects() {
return objects_.size();
}
Object* CreateObject(size_t index) {
return objects_[index]->CreateObject();
}
std::string GetObjectInfo(size_t index) {
return objects_[index]->GetObjectInfo();
}
private:
std::vector<IObjectProxy*> objects_;
};
// This is the factory proxy template class
template<typename T>
class ObjectProxy : public IObjectProxy {
public:
ObjectProxy() {
ObjectFactory::Instance().AddObject(this);
}
Object* CreateObject() {
return new T;
}
virtual std::string GetObjectInfo() {
return T::TalkToMe();
};
};
objects.h
#include <iostream>
#include "object_factory.h"
// Base object class
class Object {
public:
virtual ~Object() {}
};
class ClassA : public Object {
public:
ClassA() { std::cout << "ClassA Constructor" << std::endl; }
~ClassA() { std::cout << "ClassA Destructor" << std::endl; }
static std::string TalkToMe() { return "This is ClassA"; }
};
class ClassB : public Object {
public:
ClassB() { std::cout << "ClassB Constructor" << std::endl; }
~ClassB() { std::cout << "ClassB Destructor" << std::endl; }
static std::string TalkToMe() { return "This is ClassB"; }
};
objects.cpp
#include "objects.h"
// Objects get registered here
ObjectProxy<ClassA> gClassAProxy;
ObjectProxy<ClassB> gClassBProxy;
main.cpp
#include "objects.h"
int main (int argc, char * const argv[]) {
ObjectFactory& factory = ObjectFactory::Instance();
for (int i = 0; i < factory.NumberOfObjects(); ++i) {
std::cout << factory.GetObjectInfo(i) << std::endl;
Object* object = factory.CreateObject(i);
delete object;
}
return 0;
}
output:
This is ClassA
ClassA Constructor
ClassA Destructor
This is ClassB
ClassB Constructor
ClassB Destructor
If you're on Windows, and using C++/CLI, this becomes fairly easy. The .NET framework provides this capability via reflection, and it works very cleanly in managed code.
In native C++, this gets a little bit trickier, as there's no simple way to query the library or application for runtime information. There are many frameworks that provide this (just look for IoC, DI, or plugin frameworks), but the simplest means of doing it yourself is to have some form of configuration which a factory method can use to register themselves, and return an implementation of your specific base class. You'd just need to implement loading a DLL, and registering the factory method - once you have that, it's fairly easy.
Something you can consider is an object counter. This way you don't need to change every place you allocate but just implementation definition. It's an alternative to the factory solution. Consider pros/cons.
An elegant way to do that is to use the CRTP : Curiously recurring template pattern.
The main example is such a counter :)
This way you just have to add in your concrete class implementation :
class X; // your interface
class MyConcreteX : public counter<X>
{
// whatever
};
Of course, it is not applicable if you use external implementations you do not master.
EDIT:
To handle the exact problem you need to have a counter that count only the first instance.
my 2 cents
There is no way to query the subclasses of a class in (native) C++.
How do you create the instances? Consider using a Factory Method allowing you to iterate over all subclasses you are working with. When you create an instance like this, it won't be possible to forget adding a new subclass later.