2010-07-14 5 views
0

저는 멤버 함수에 대한 포인터를 처음 접했고, 장단점을 알고 싶습니다.멤버 함수에 대한 포인터의 사용과 유용성에 대해

는 특히이 사항을 고려하십시오

주석에 명시된 바와 같이
#include <iostream> 
#include <list> 

using namespace std; 

class VariableContainer; 

class Variable 
{ 
public: 
    Variable (int v) : value (v), cb_pointer (0) {} 
    ~Variable() {} 

    void SetCallback (void (VariableContainer::*cb)(int)) { 
    cb_pointer = cb; 
    } 
    void FireCallback (void) { 
    /* I need a reference to a VariableContainer object! */ 
    } 

private: 
    int value; 
    void (VariableContainer::*cb_pointer) (int); 
}; 

class VariableContainer 
{ 
public: 
    VariableContainer() {} 
    ~VariableContainer() {} 

    void AddVar (Variable &v) { 
    v.SetCallback (&VariableContainer::Callback); 
    } 
    void Callback (int v) { cout << v << endl; } 
}; 

int main() 
{ 
    Variable v (1); 
    VariableContainer vc; 

    vc.AddVar (v); 
    v.FireCallback(); 

    return 0; 
} 

는, 콜백 (FireCallback) 내가 VariableContainer::AddVar (...)의 추가 인수로 제공해야한다 기존 VariableContainer 객체, 일부 참조가 필요 트리거 할 수 있습니다. Now :

  1. 멤버 함수에 대한 포인터를 사용해야합니까? 또는 VariableContainer 개체에 대한 포인터가 있으므로 Callback (...)을 직접 호출해야합니까?
  2. 각 솔루션의 장점과 단점은 무엇입니까?

TIA, JIR은

+0

유용 할 수 있습니다. http://stackoverflow.com/q/3957348/15161 – slashmais

답변

2

미래에 달라질 수 있습니다 무엇에 따라 결정할 수 있습니다 :

  • 다른 기능에 의해 호출 될 변수의 FireCallback => 포인터 - 투 - MF가 유용 할 수 있지만, 다른 메커니즘이 더 다 있습니다 ++ ish
  • '콜백'기능 만 호출되며 =>arg->CallBack()을 직접 호출합니다.

이 문제에 대한 가능한 해결책은 인터페이스 레이어를 사용하는 것입니다. 이것은 관찰자 패턴을 구현 한 것일뿐입니다. 이것은 좀 더 많은 객체 지향 (OO)이므로, 장황하다.

class Observer { 
public: 
    virtual ~Observer(){}; 
    virtual void callback(int v) = 0; 
}; 

// actual implementation 
class MyCallbackObserver : public Observer { 
    virtual void callback(int v) { std::cout << v << std::endl; } 
    void some_other_method(int v) { std::cout << "other " << v ; } 
}; 

그리고 당신의 Variable 클래스는 관찰자의 전체 컨테이너 것이다 :

class OtherCaller: public Observer { 
public: 
    MyObserver* obs; 
    virtual void callback(int v) { obs->some_other_method(v); } 
} 
: 다른 기능은 같은 객체에서 호출해야하는 경우에는 래퍼를 소개 할 수

class Variable { 
public: 
    std::vector<Observer*> observers; // warning: encapsulation omitted 
    void FireCallback(){ 
     // assuming C++ 0x 
     for(auto it : observers) { 
     (*it)->Callback(value); 
     } 
    } 

컬렉션에 추가 :

+0

간결하지만, 철저한 설명. 감사! 이제 직접 호출은 간단하지만 PMF와는 달리 확장 성이 떨어지는 것을 알았습니다. Observer 패턴을 지적 해 주셔서 감사합니다. – Jir

1

그것은 당신의 요구에 현재 위치에 따라 달라집니다.

콜백 함수가 하나 뿐이며 이름을 항상 알고 있다면 직접 호출 할 수도 있습니다. 이해하기 쉽고 간단하며 추가 변수가 필요하지 않습니다.

구성 함수 포인터는 구성에 따라 여러 콜백 중 하나를 호출 할 필요가있는 경우 유용합니다. 콜백 멤버 함수 포인터를 호출 할 실제 콜백으로 설정 한 다음이를 선택하는 데 사용됩니다 실행할 콜백.

+0

유용한 설명입니다. 고맙습니다! – Jir

관련 문제