@selector implementation in C++
I need to implement similar mechanism like @selector(Objecitive-C) in C++. By googling i have found. It does not help me...
template <class AnyClass>
class ClassCallback
{
// pointer to member function
void (AnyClass::*function)(void);
// pointer to object
AnyClass object;
public:
ClassCallback() { }
~ClassCallback() { }
ClassCallback(AnyClass _object, void(AnyClass::*_function)(void))
: object( _object ), function( _function ) { };
开发者_如何学C virtual void call(){
(object->*function)();
};
};
Is there any different approach to implement which is similar to objective-C like
typedef struct objc_selector *MY_SEL;
Need to implement objc_selector It is abstract class in objective-C. How to implement objc_selector any idea...
Just a few precisions on the Objective-C messaging system, with the selectors.
A selector (SEL) is an opaque type, but it's only something like a char *
, containing only the name of the method (so many classes can share the same selector).
An Obj-C method is a struct containing:
- A
SEL
field - A
char *
containing infos about the return type and arguments. - An
IMP
field
Something like:
struct objc_method
{
SEL method_name;
char * method_types;
IMP method_imp;
};
typedef objc_method Method;
An IMP
is just a C function pointer.
Objective-C and C++ are very different languages, and as far as I know C++ doesn't have anything equivalent or even similar to Objective-C's selectors. If you explain the problem you're trying to solve, I'm sure someone here will be happy to discuss the way that problem might be dealt with from a C++ perspective.
If you're happy with using a custom preprocessor before compiling C++ files, you can use Qt's signal and slot mechanism, which is an implementation of message-passing system in a slightly-extended C++. See here.
You might want to do something like this :
// We use something to define what "identifies" a
class selector {
private:
std::string name;
public:
selector(std::string const& n) : name(n) {}
selector(const char* n) : name(n) {}
};
typedef const selector* SEL;
Use it like this :
typedef void* (*method) (object&, ...);
struct object {
private:
std::hash<SEL,method>* methods;
public:
object(std::map<SEL,method>* m) : methods(m) {};
};
selector cloneSelector = selector("clone");
typedef void* cloneImplementation(object&, ...) {
....
};
Use it like this :
std::map<SEL,method> fooMethods;
fooMethods[cloneSelector]=&cloneImplementation;
class foo : public object {
public:
foo() : object(&fooMethods) {};
};
There are several problems however (typing, function signature …). You probably do not want to do this.
Ohterwise, look at the code. Gobjc is open source, it is quite simple to see how it is done. Looking at objc/deprecated/struct_objc_selector.h of (GNU) gobjc I find:
struct objc_selector
{
void *sel_id;
const char *sel_types;
};
AFAIK sel_id is a pointer to a string made of the method name and the (encoded) argument types.
You might want to group methods in interfaces and have a slightly more "COM-ish" way of doing it :
struct interface_id {};
class object {
protected:
virtual void* getVtable_(interface_id const&) = 0;
public:
template<class X> X* getVtable() {
return getVtable(X::interface_id);
}
virtual ~object();
};
// Exemple interface
struct FooInterface {
public:
class vtable {
void (*fooMethod2)(void* self, int n);
std::vector<int> (*fooMethod2)(void* self, double x);
};
static interface_id ID;
static std::string NAME; // = "FooInterface"
private:
void* self;
FooVtable* vtable;
public:
void fooMethod1(int n) {
return vtable->fooMethod1(self,n);
};
void fooMethod2(double x) {
return vtable->fooMethod2(self,double x);
};
};
// Exemple object
class foo_object : public bar_object {
private:
static std::map<interface_id, void*> INTERFACES;
public:
virtual void* getVtable_(interface_id const& id) {
void* res = INTERFACES[&id];
if(res!=null)
return res;
else
return bar_object::getVtable(id);
};
};
It gives an an idea of how to enforce function signatures. You should be able to use the same kind of thing for the selector-based approach (using some boring template-meta-programming code …).
I had a similar problem when using Cocos2d-x, and in my case I used callfunc_selector
to get the selector:
Suppose a class Foo
and a method Bar()
inside it, just call callfunc_selector(Foo::Bar);
and it will return a CCObject*
to the method.
精彩评论