2010-02-06 3 views
0

안녕하세요, 일반 멤버 함수 포인터에 대한 질문이 있습니다. 다음 질문과 비슷한 것을 얻으려고합니다. How to define a general member function pointer일반 멤버 함수 포인터 도움말

본질적으로 할 수있는 일은 일반적인 이벤트 객체를 인수로 사용하여 특정 이벤트 유형 (예 : , KeyboardEvent). 그런 다음 입력 관리 클래스에서 사용자가 키를 친 때마다 키 누르기에 대한 일부 데이터가 포함 된 KeyboardEvent 객체를 만들고 등록 된 모든 멤버 함수 포인터를 호출 할 수 있습니다. 내 KeyboardEvent 객체를 매개 변수로 사용하여 KeyboardEvent 유형

나는 boost bind와 boost 함수로 놀아 왔고, 그들은 내가하고 싶은 것의 95 %를 할 수있게 해주는 것 같다. 나는 모든 멤버 함수 포인터를 벡터에 저장하려고한다. ,하지만 그들은 모두 다른 유형의 그래서 나는 그것을 할 수 없습니다. 따라서 먼저 이벤트 처리 시스템에 메서드를 등록 할 때 함수 개체에 바인딩합니다.이 시스템에서는이 시점에서 모든 인수를 지정해야합니다. 개체가 미래의 알려지지 않은 이벤트에 의해 생성되기 때문에 나는이 시점에서 개체를 가질 필요가 없습니다.

죄송합니다. 아무 의미가없는 경우 죄송합니다.

+0

몇 가지 단락을 제외하고는 질문이 무엇인지 분명하지 않습니다. 뭐, 정확하게 알고 싶니? 벡터에 여러 유형의 객체를 저장하는 방법은 무엇입니까? 또는 다른 것? 코드 스 니펫도 항상 도움이됩니다. – SoapBox

답변

3

은 (여기에 모든 Boost.Signals2 물건없이 부스트 : : 기능/바인드 문제에 더 직접적인 대답.) 당신이 등 _1, _2를 사용하지 않는 것 같다

boost :: bind 사용할 때 자리 표시 자. 이 예제는 어떻게 사용해야하는지 보여줍니다 :

struct KeyboardEvent { char key; }; 

typedef boost::function<void (KeyboardEvent)> KeyboardHandler; 

struct Handler 
{ 
    void onKey(KeyboardEvent event) {std::cout << event.key;} 
}; 

int main() 
{ 
    Handler handler1, handler2; 
    std::vector<KeyboardHandler> handlers; 
    handlers.push_back(boost::bind(&Handler::onKey, &handler1, _1)); 
    handlers.push_back(boost::bind(&Handler::onKey, &handler2, _1)); 
    KeyboardEvent event; 
    event.key = 'z'; 
    handlers[0](event); 
    handlers[1](event); 
} 
+0

와우,이게 그랬어. 나는 이것을 일찍 시도했지만 컴파일하지는 않았다. 나는 틀린 뭔가를하고 있었음에 틀림 없다. 도움을 많이 주셔서 감사합니다. 그리고 관찰자 패턴에 대한 링크에 감사드립니다. 나는 그것을 읽어야 할 것이다. 나는 C++에서 이미 존재한다는 것을 깨닫지 못했다. 나는 Actionscript 3 이벤트 이후에 디자인을 모델링 한 것뿐입니다. – Morgan

0

내가 제대로 질문을 이해한다면, 당신은 내가 당신의 질문, 그리고 마지막으로 잡은 멤버 함수 부분을 다시 읽어

// function pointer, function with similar signature can be cast as function_t 
typedef int (*function_t)(object_t *event, ...); 
std:: vector<function_t> function_pointers; 

// populate vector, e.g. function_pointers.push_back((function_t)&some_function) 

void handle_event(object_t *event) { 
    for (...) (function_pointers.at(i))(event, ...); 
} 

다음 시도 할 수 있습니다. 이것을 위해 펑터를 사용할 수 있습니다.

struct base { 
    virtual void function(event_t *event)= 0; 
}; 

template<class A> 
struct F : base { 
    F(A &a) : object_(a) {} 
    virtual void function(event_t *a) { object_.function(a); } 
    A &object_; 
}; 

std:: vector<base*> callback_vector; 
... 
callback_vector.push_back(new F<event_handler>(event_handler_object)); 
0

이 정말 당신의 문제에 대한 답하지만, 단지 당신이 달성하기 위해 노력하고 무엇 이미 존재한다는 것을 암시하지 않습니다.

Observer 패턴을 구현하려는 것 같습니다. 당신은 그것에 대해 here 읽을 수 있습니다. Observer 패턴을 파악한 후 Boost.Signals2 라이브러리를 확인하십시오. boost::signal은 이벤트 핸들러 함수 포인터의 벡터와 비슷하지만 훨씬 강력합니다.

다음은 입력 된 문자를 감지하기 위해 Boost :: Signals2를 사용하는 예입니다. 희망이 도움이됩니다.

#include <iostream> 
#include <boost/signals2.hpp> 
#include <boost/bind.hpp> 

//----------------------------------------------------------------------------- 
struct KeyboardEvent 
{ 
    char key; 
}; 

//----------------------------------------------------------------------------- 
class Keyboard 
{ 
private: 
    typedef boost::signals2::signal<void (KeyboardEvent)> SignalType; 
    SignalType signal_; 

public: 
    typedef SignalType::slot_type SlotType; 

    // Subscribes to keyboard events 
    boost::signals2::connection connect(const SlotType& slot) 
    { 
     return signal_.connect(slot); 
    } 

    // Scans for keyboard events and notifies subscribers 
    void scan() 
    { 
     KeyboardEvent event; 
     std::cin >> event.key; 
     signal_(event); 
    } 
}; 

//----------------------------------------------------------------------------- 
class KeyPrinter 
{ 
private: 
    void onKey(KeyboardEvent event) 
    { 
     std::cout << "You hit \'" << event.key << "\'\n"; 
    } 

    boost::signals2::connection connection_; 

public: 
    void connect(Keyboard& keyb) 
    { 
     connection_ = keyb.connect(
      boost::bind(&KeyPrinter::onKey, this, _1)); 
    } 
    void disconnect() {connection_.disconnect();} 
}; 

//----------------------------------------------------------------------------- 
class Quitter 
{ 
private: 
    void onKey(KeyboardEvent event) 
    { 
     if (event.key == 'q' || event.key == 'Q') {quit_ = true;} 
    } 

    boost::signals2::connection connection_; 
    bool quit_; 

public: 
    void connect(Keyboard& keyb) 
    { 
     quit_ = false; 
     connection_ = keyb.connect(
      boost::bind(&Quitter::onKey, this, _1)); 
    } 
    void disconnect() {connection_.disconnect();} 
    bool quitDetected() {return quit_;} 
}; 

//----------------------------------------------------------------------------- 
int main() 
{ 
    Keyboard keyb; 
    KeyPrinter printer; 
    Quitter quitter; 

    printer.connect(keyb); 
    quitter.connect(keyb); 

    while (!quitter.quitDetected()) 
    { 
     keyb.scan(); 
    } 
}