簡體   English   中英

C++ 中的@selector 實現

[英]@selector implementation in C++

我需要在 C++ 中實現類似 @selector(Objecitive-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 中的抽象 class。 如何實現 objc_selector 任何想法......

在 Objective-C 消息傳遞系統上只需幾個精度,帶有選擇器。

選擇器 (SEL) 是一種不透明類型,但它只是類似於char *的東西,僅包含方法的名稱(因此許多類可以共享相同的選擇器)。

Obj-C 方法是一個包含以下內容的結構:

  1. SEL字段
  2. 一個char *包含有關返回類型和 arguments 的信息。
  3. 一個IMP字段

就像是:

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

IMP只是一個 C function 指針。

我在使用 Cocos2d-x 時遇到了類似的問題,在我的情況下,我使用callfunc_selector來獲取選擇器:

假設一個 class Foo和其中的方法Bar() ,只需調用callfunc_selector(Foo::Bar); 它會向該方法返回一個CCObject*

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

然而,有幾個問題(打字,function 簽名......)。 您可能不想這樣做。

否則,請查看代碼。 Gobjc 是開源的,很容易看到它是如何完成的。 查看 (GNU) gobjc 的 objc/deprecated/struct_objc_selector.h 我發現:

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

AFAIK sel_id 是指向由方法名稱和(編碼)參數類型組成的字符串的指針。

您可能希望對接口中的方法進行分組,並采用一種更“COM-ish”的方式:

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

它提供了如何強制執行 function 簽名的想法。 您應該能夠對基於選擇器的方法使用相同的東西(使用一些無聊的模板元編程代碼......)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM