2013-03-18 34 views
0

我正在研究基於簡單的event-system的庫。std ::綁定在類的內部,事件系統的一般概念

對於使用GUI元素(「控件」)的工作,這些都需要很多。例如,Window類有許多事件,如「onMouseMove」,「onKeyPress」,「onKeyRelease」,但是,控件的基本類是Control類。它有一個虛擬函數繪製(顯然繪製了控件)和一個連接控件和主窗口事件的虛擬函數連接(類似於Qt Signal-Slot-Concept)。

但是由於Event類將std::function<...>指針作爲主題(=> Slot),所以我不能簡單地將派生控件類的成員函數與窗口事件連接起來。作爲一種變通方法,我做以下的事情:

class A : public Control { 
    friend class Window; 

    public: 
     A(){ 
      this->eventHandler = [this]() -> void { 
       if (someCondition) this->onSomeCondition.notify(); 
      }; 
     } 

     Event<> onSomeCondition; 

    protected: 
     std::function<void()> eventHandler; 

     void connect(Window *window){ 
      window->onSomeHigherEvent.attach(&this->eventHandler); 
     } 

     void draw(...) const{ 

      drawSome(...); 

     } 

}; 

什麼這通常做的就是,它在構造函數中分配一個lambda函數的std::function<...>並附着該std::function<...>所選擇的事件。

雖然存在一個主要問題:如果我實例化該類的更多對象會發生什麼?如果我有在類中指定的事件處理程序,作爲一個正常的功能,像這樣:

void eventHandler() { 
    if (someCondition) this->onSomeCondition.notify(); 
} 

而且可以分配使用std::bind該函數將std::function<...>,不出於某種原因,至少只要我「M使用下面的調用:

std::bind(&A::eventHandler, this, std::placeholders::_1); // *this will not work since that's just a (reference to the?) copy to of the object. 

不管怎麼說,拉姆達功能,解決方法似乎是更短的時間有效,因爲它不是真正的內置類。有沒有更有效的方法來解決這個問題?也許不是通過解決lambda函數問題,而是通過改變概念?

+0

「這不會出於某種原因,」對於建立什麼實際上可能是錯誤的一個相當無用的錯誤報告。 – 2013-03-18 16:48:49

+0

我個人寫了一個名爲[SPARK 2](http://spark.developpez.com/index.php?lang=en)的粒子系統的信號槽系統(現在還沒有完全完成)。目標也是與C++ 03編譯器兼容,所以我通過使用指向成員的指針和指向對象的指針來完成它。可能比lambda更有記憶力,超快,因爲它使用了很多模板(例如函數指針作爲模板參數)。 – Synxis 2013-03-18 16:50:30

回答

2

我不知道你的問,因爲我無法找到的問題,但是...

std::bind(&A::eventHandler, this, std::placeholders::_1); // *this will not work since that's just a (reference to the?) copy to of the object.

這將創建一個具有一個未綁定的參數調用對象,即它期望被一個參數調用,它與std::function<void()>不兼容,因爲這是一個函數,期望不帶任何參數被調用。它也與您展示的eventHandler成員函數不兼容,因爲它也沒有任何參數。

也許你只是想用std::bind(&A::eventHandler, this);

+0

噢,對不起,這是完全沒有上下文..當然這需要一個參數(這是在實際的程序中給出),但實際的問題是綁定函數在當前對象的上下文,分別'this'。當綁定'this'或'* this'( - >拷貝(!)'this'的內容),g ++拋出一個大的錯誤信息並終止。 – dasdave 2013-03-18 20:18:32

+1

因此,更新問題以顯示錯誤消息,以及完整的示例,或者人們在沒有上下文的情況下進行猜測。在'std :: bind'中使用'this'可以正常工作,所以你必須做一些錯誤的事情。解決這個問題,你不必擔心_「無論如何,它似乎沒有時間效率,因爲它沒有真正構建到課堂中」。 – 2013-03-18 23:06:53