2013-06-11 2 views
0

클래스 멤버 함수를 하위 클래스 (파생되지 않음)에 전달하는 방법에 대해 고민하는 데 어려움이 있습니다.클래스 간의 함수 포인터

내 최상위 클래스는 다음과 같이이다 :

그래서 기본적으로 여기
class CFnList 
{ 
public: 
    // Public functions 
    CFnList(); 
    void addFnPtrToList(int index, int (*fn)(void)); 

private: 
    // Fn pointer list 
    typedef struct 
    { 
     int index; 
     int (*fn) (void); 
    }fn_list_t; 

    // function pointer list 
    QVector<fn_list_t> _fn_list; 
}; 

내가 클래스 CTop의 인스턴스를 멤버 중 하나입니다 :

class CTop 
{ 
public: 
    CTop(); 
    int func1(void); 

private: 
    CFnList* _funcList; 
}; 

CTop::CTop(): 
    _funcList(0) 
{ 
    _funcList = new CFnList(); 
    _funcList->addFnPtrToList(0, &CTop::func1); 
} 

int CTop::func1(void) 
{ 
    // Does some stuff... 
} 

내 기능 목록 클래스는 다음과 같이이다 클래스 CFnList에 대한 포인터. CFnList 포인터는 CTop의 생성자에서 인스턴스화됩니다. 다음 줄을 호출하여 CTop의 멤버 함수 중 하나에 대한 포인터를 CFnList에 전달하려고합니다. "_funcList-> addFnPtrToList (0, & CTop :: func1);" addFnPtrToList가 매개 변수 (int, (CTop :: *)())를 사용하지 않는다는 문제가 있습니다. 따라서 컴파일러는이 함수가 특정 멤버 함수이고 일반 (어쩌면 정적 인) 함수가 아니라는 것을 알고 있습니다.

멤버 함수에 대한 포인터를 하위 클래스로 전달할 수있는 방법이 있습니까? 제 경우에는 하위 클래스가이 함수를 호출 할 수 있기를 원합니다. 나는 아마도 정적 멤버 함수 나 뭔가를 만들 필요가 있다고 생각하지만 구문은 이것을 수행하는 방법을 알지 못한다.

모든 도움/조언 부탁드립니다. 사료

+0

사과 기여한 모든 사람에게

감사 O를, 나는 시간이 실행 ​​한 내 일 :( –

답변

3

선언 :

int (*fn)(void) 

이 멤버 함수를 가리킬 수 없다. 자유로운 기능 만 가리킬 수 있습니다. 필사적으로, 이것은 멤버 함수의 호출 규칙이 자유 함수의 호출 규칙과 다르므로 가능합니다. 예를 들어 멤버 함수 호출의 컨텍스트에서 포인터가 필요하다고 생각하십시오.

포인터 멤버 함수를 선언하기위한 구문은 다음과 같다 :

int (CTop::*fn)(void) 

멤버 함수 포인터 전용 C++ FAQ의 전체 섹션이있다. 확인 해봐.

+0

좋은 게시물 +1 :) ... 내 경우에는 CFnList 클래스를 사용하고자하는 "CTop"유형 클래스가 두 개 더 많아서 객체 유형을 구체적으로 말하면 실제로는 나를위한 옵션이 아닙니다. 하나, 나는 아침에 이것을 확실히 읽을 것입니다! –

+0

이것이 결국 효과가 있었던 방법 이었기 때문에 ... 답을 선택하는 것을 잊었습니다. –

4

CTop::func1은 구성원 기능입니다. &CTop::func1은 함수 포인터가 아니며 멤버 (함수)에 대한 포인터입니다. 그것들은 저장이나 호출에서 혼합 될 수 없습니다. 후자는 인수를 사용하지 않고 전자는 숨겨진 것으로 전달 된 객체가 필요하므로 int (*fn)(void)과 호환되지 않습니다. this.

이러한 이유로 인해 단순하지만 일관된 기능을 사용할 수 없습니다. 간단한 함수 포인터 또는 PTM + 오브젝트 포인터 쌍을 사용하거나 핸드 메이드 또는 boost::function 같은 주식을 boost::bind에 의해 사용하는 래퍼를 사용할 수 있습니다. C++ 11 또는 TR1을 사용하는 경우 std :: equivalents를 사용할 수 있습니다. 형태

+0

감사의 말은 귀하의 코멘트 :) 나는 당신이 (+1) "쌍의 PTM + 개체 포인터"기대 강조 표시된 모든 옵션을 이해합니다. 그게 뭐지 ... 그 소리는 내가 원하는 것을 할 수있는 것처럼 보이는데 이는 물건뿐만 아니라 회원 (기능)을 지나쳐서 ... 이런 식으로? –

+0

예, 포인터 pFn과 인스턴스 pTop에 대한 포인터가 있으면 실제 호출을하는'(pTop -> * pFn) (ARGS)'를 발행 할 수 있습니다. 고정 유형 및 서명을 위해 쌍을 저장하는 것은 어렵지 않습니다. –

1

멤버 함수를 일반 함수처럼 전달하고 있습니다. 그것은 '이'참조를 수업에 포함시키지 못한다. 멤버 함수를 전달하려면 원래 'this'에서 다시 참조 할 수 있어야합니다. 대신 다음을 살펴보십시오.

typedef void (CTop::*OBJFNC)(args); 

_funcList = new CFnList(); 
_funcList->addFnPtrToList(0, this, &CTop::func1); 


void addFnPtrToList(int index, CTop* pobj, OBJFNC pfnc) 
{ ... Store both ... 
} 

다른 곳에서는 다음과 같이 실행할 수 있습니다.

내 최상위 클래스는 다음과 같이이다 (더 많거나 적은 같은 :

(pobj->*pfnc)(args); 
+0

게시물을 가져 주셔서 감사합니다. 멋진 아이디어 +1 :)하지만 John의 게시물과 비슷한 문제가 있습니다. 나는 명시 적으로 Object 형을 사용할 수 없다. 왜냐하면 내 코드에는 CFnList를 사용하여 해당 함수에 대한 포인터를 저장하려는 클래스와 같은 "CTop"이 많이있다. –

+0

하나의 잠재적 인 솔루션은 모든 클래스가 공통 기본 클래스를 상속 받고 함수 오버로드를 사용하는 것입니다. 그렇게하면 목록 유지자가 CTopInheritedClass ptrs에 대한 참조를 유지할 수 있습니다. 그것이 내가 생각할 수있는 전부입니다. 어느 쪽이든, 당신은 원래의 'this'에 대한 포인터를 어떤 형태로 또는 유행으로 유지해야 할 것입니다. – Lee

0

여기에 최종 솔루션입니다, 그것은 개체 CTop 및 템플릿 클래스의 사용 CFnList에 대한 인스턴스를 전달하는 혼합물을 사용하여 _funcList의 선언을 제외하고에 클래스 종류와 "이"로 생성자에 전달이 포함

class CTop 
{ 
public: 
    CTop(); 
    int func1(void); 

private: 
    CFnList<CTop>* _funcList; 
}; 

CTop::CTop(): 
    _funcList(0) 
{ 
    _funcList = new CFnList(this); 
    _funcList->addFnPtrToList(0, &CTop::func1); 
} 

int CTop::func1(void) 
{ 
    // Does some stuff... 
} 

내 기능 목록 클래스는 다음과 같이이다 :

template<class T> 
class CFnList 
{ 
public: 
    // Public functions 
    CFnList(T *parent); 
    void addFnPtrToList(int index, int (T::*fn)(void)); 

private: 
    // Pointer to the parent (or owner is perhaps more correct) 
    T* _parent; 

    // Fn pointer list 
    typedef struct 
    { 
     int index; 
     int (T::*fn) (void); 
    }fn_list_t; 

    // function pointer list 
    QVector<fn_list_t> _fn_list; 
}; 

// Constructor 
template <class T> 
CFnList<T>::CFnList(T *parent) : 
    _parent(parent), 
    _fn_list(0) 
{ 
} 

// addFnPtrToList: 
template <class T> 
void CFnList<T>::addFnPtrToList(int index, int (T::*fn)(void)) 
{ 
    _fn_list.append((fn_list_t){index, fn}); 
} 

주요 변경 내용은 다음과 같습니다. 1. 변경하는 CFnList를 템플릿으로 사용하여 CTop 형식을 전달합니다. 2. "this"를 생성자에 전달하여 객체 CTop의 인스턴스를 전달합니다 (함수 포인터가 호출 될 수 있도록). 그러면 템플릿 클래스가 주어진 템플릿 유형에 대한 포인터로 저장합니다. -la ... 쉽게!) : 내 측면에서 어떤 느린 응답에 대한

+0

관련성이 없기 때문에 실제로이 주제를 게시 할 예정입니다. 그런 다음 솔루션을 작동 시키면이 게시물을 업데이트합니다. 미안 누군가가 혼란/문제가 발생하면! –

+0

해당 템플릿 문제가 해결되었으므로 완전한 솔루션을 게시했습니다. 덕분에 모두 :) –

관련 문제