c++中@selector的实现

objective c - @selector implementation in C++

本文关键字:实现 @selector c++      更新时间:2023-10-16

我需要在c++中实现类似于@selector(objective -C)的机制。通过谷歌我发现。这对我没有帮助。

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 ) { };
    virtual void call(){ 
         (object->*function)();
    };
};

是否有其他类似于objective-C的实现方法,如

typedef struct objc_selector    *MY_SEL;  

需要实现objc_selector它是objective-C中的抽象类。如何实现objc_selector任何想法…

在Objective-C消息传递系统中使用选择器进行一些精确的操作。

选择器(SEL)是一种不透明类型,但它只是像char *一样,只包含方法的名称(因此许多类可以共享相同的选择器)。

Obj-C方法是一个结构体,包含:

  1. SEL字段
  2. 包含返回类型和参数信息的char *
  3. IMP字段

类似:

struct objc_method
{
    SEL    method_name;
    char * method_types;
    IMP    method_imp;
};
typedef objc_method Method;

IMP只是一个C函数指针。

Objective-C和c++是非常不同的语言,据我所知,c++没有任何等同于甚至类似于Objective-C的选择器。如果你解释了你要解决的问题,我相信这里有人会很乐意讨论从c++的角度来解决这个问题的方法。

如果您喜欢在编译c++文件之前使用自定义预处理器,则可以使用Qt的信号和槽机制,这是在稍微扩展的c++中实现的消息传递系统。看到这里。

您可能想要这样做:

// 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;

像这样使用:

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&, ...) {
  ....
};

像这样使用:

std::map<SEL,method> fooMethods;
fooMethods[cloneSelector]=&cloneImplementation;
class foo : public object {
public:
  foo()  : object(&fooMethods) {};
};

然而有几个问题(打字,函数签名…)。您可能不希望这样做。

否则,查看代码。Gobjc是开源的,很容易看到它是如何实现的。查看objc/deprecated/struct_objc_selector.h of (GNU) gobjc,我发现:

struct objc_selector
{
  void *sel_id;
  const char *sel_types;
};

AFAIK sel_id是一个指针,指向一个由方法名和(编码的)参数类型组成的字符串。

您可能希望在接口中对方法进行分组,并采用更"com"的方式进行分组:

 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);
   };
};

它给出了一个如何强制函数签名的概念。您应该能够对基于选择器的方法使用相同的东西(使用一些无聊的模板元编程代码…)。

我在使用Cocos2d-x时遇到了类似的问题,在我的情况下,我使用callfunc_selector来获取选择器:

假设有一个类Foo,其中有一个方法Bar(),只需调用callfunc_selector(Foo::Bar);,它将返回一个CCObject*给该方法。