簡體   English   中英

C ++ ::成員函數數組

[英]C++:: Array of Member Functions

我想存儲不同類的成員函數數組。 這里只是重復:

要求:

  • TypeOf
  • 包含函數的類的實例
  • AddressOf成員函數
  • 成員函數參數

我可以存儲什么:

  • 包含函數的類的實例
  • 成員函數的AddressOf
  • 成員函數參數

通常,您無需存儲任何Class類型,因為您可以使數組指針指向Class類型。 我之所以不能這樣做,是因為我接受的Class類型是未知且不同的。 該類將用於許多類類型未知的項目中。

我需要將不同類型的類存儲到數組/列表中,在這種情況下,我只是將類的地址存儲到數組指針中。

我的問題:當我要調用成員函數時,我需要將Class地址轉換為Class類型,但是我不知道該轉換為哪種類型。

示例代碼(未經測試-快速編寫):

class A
{
    public:
        void test1(int i);
};

class B
{
    public:
        void test2(char c);
};

class Container
{
    long* objects;
    long* funcs;
    int index;

    public:

        Container()
        {
            objects = new long[5];
            funcs = new long[5];
            index = 0;
        }

        template <class C, typename Types ...>
        void Add(C *obj, void (C::*func)(Types ...))
        {
            objects[index++] = (long)obj;
            funcs[index++] = (long)func;
        }

        typename <Types ...>
        void Call(int inx, Types ... values)
        {
            void (*func)(Types ...) = (void (*)(Types ...))funcs[inx];

            // This is where I've got trouble. I don't store the Class 
            // types, so I don't know what pointer Class type to cast 
            // the Class Instance address to.
            (((*???)objects[inx])->*func)(values ...);
        }
};

提前致謝。 事先詢問是否有孔或任何問題。

您可以在成員函數的簽名上對此加以限制嗎? 如果是這樣,您可以存儲綁定的函數,而不必分別存儲指向對象和成員函數的指針。

template<typename... Args>
class Container {
public:
    typedef std::function<void (Args...)> F;

    template <class C>
    void Add(C* obj, void (C::*func)(Args ...))
    {
        functions.push_back( [=](Args... args) {(obj->*func)(args...);} );
    }

    void call(size_t i, Args... args)
    {
        functions[i](args...);
    }

private:
    std::vector<F> functions;
};

恕我直言,您的帖子看起來像是一個有趣的多態編程挑戰,但是有一個額外的要求,即“禁止多態” ...在這種情況下,您將學習更困難的方法。

我要解決您所說的問題:

當我要調用成員函數時,我需要將Class地址轉換為Class類型,但是我不知道該類型轉換為什么類型。

曾經被稱為Thunk(當我第一次遇到它的時候)。 在(相對)最近的搜索中,我沒有用這個名字找到這個想法(並且確實找到了其他一些叫做thunk的東西)。 我曾經讀過的名字的解釋就像是因為“它封裝了我已經笨拙的東西”。

請注意,使用重擊時,不需要強制轉換(因為您已經將其重擊了)

將thunk用作容器中的對象。

哦,既然您已標記此C ++,則實際上應該使用std :: vector <PVThunk_t>。

  // ////////////////////////////////////////////////////////////////////
  // Pure Virtual Thunk_t: an abstract base class
  class PVThunk_t
  {
  public:
     virtual ~PVThunk_t(){}

     virtual void operator()(void* v) = 0;
     virtual void exec      (void* v) = 0;
  };
  // pure-virtual requires derived objects to implement both methods

// ///////////////////////////////////////////////////////////////////////
// template class - make it easy to create thunk for any class T
template <class T>
class Thunk_t : PVThunk_t
{
public:
   // constructor - takes pointer to an object and pointer to a member and stores
   // them in two private variables
   Thunk_t( T*    anInstance,        // pointer to an instance of class T
            void* (T::*aMethod)()) : // pointer to a  method   of class T, no parameter, returns void
      m_instance (anInstance),
      m_method   (aMethod)
      {
         assert  (m_instance);
         asssert (m_method);
      }

   Thunk_t( T*  anInstance,        // pointer to an instance of class T
            T*  (T::*aMethod)()) :  // pointer to a  method   of class T, no parameter, returns T*
      m_instance (anInstance),
      m_method   (aMethod)
      {
         assert  (m_instance);
         asssert (m_method);
      }

   virtual ~Thunk_t() { }

   // override operator "()"
   virtual void* operator()(void* v) { return((*m_instance.*m_method)(v)); }

   // override function "exec"
   virtual void* exec(void* v) { return((*m_instance.*m_method)(v)); }

private:
   T*        m_instance;         // pointer to object of T
   void (T::*m_method)(void*);   // pointer to method attribute of T with void* param

}; // template <class T>  class Thunk_t : public PVThunk_t

注意聲明m_instance和m_method指針的正確機制。


如果您需要使用帶有可變數量參數的方法,建議您傳遞一個struct指針(對Thunk進行適當的調整或添加。單個方法的參數始終是指向該struct的指針,然后可以將其類型或內容設置為由調用的方法推斷。

我已經很長時間沒有使用過Thunk了,因為好吧,多態性在各個方面都優越。 但是Thunk仍然可以編譯,因此它可能會起作用。

更新-注意虛擬方法不匹配。 固定

暫無
暫無

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

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