2012-04-08 3 views
8

가상 멤버 함수와 달리, 각 클래스 파생 클래스에서 구현 된 함수를 나중에 기본 클래스에서 호출 할 수 있도록 등록 할 수있는 솔루션이 필요합니다. (가장 파생 된 구현뿐만 아니라)파생 클래스 멤버 함수 포인터를 기본 클래스로 등록하는 방법

이렇게하려면 파생 클래스가 파생 클래스 생성자와 같은 기본 클래스로 해당 함수를 등록하는 메커니즘을 제공 할 생각이었습니다.

회원 함수 포인터 인수에 문제가 있습니다. Derived가 Base에서 파생되었다고 생각했는데 포인터를 자동으로 캐스팅해야합니다.

정적 멤버 함수 인 void *static_cast을 사용해야합니까?

class Base 
{ 
protected: 
    typedef void (Base::*PrepFn)(int n); 
    void registerPrepFn(PrepFn fn) {}; 
} 

class Derived : public Base 
{ 
    Derived() { 
     registerPrepFn(&Derived::derivedPrepFn); 
    }; 

    void derivedPrepFn(int n) {}; 

} 

컴파일러 오류 :

error: no matching function for call to 'Derived::registerPrepFn(void (Derived::*)(int))' 
note: candidates are:     'void Base::registerPrepFn(void (Base::*)(int))' 
+1

정확히 무엇을하고 싶은지 잘 모르겠습니다. 그러나 이것은 확실히 불가능합니다. 'Derived '에 정의 된 멤버 함수는'Base :: *'에 의해 가리킬 수 없다. 아마도 최상위 수준의 목표를 설명하면 누군가가 더 나은 솔루션을 제안 할 수 있습니다. –

+3

FTR,'void *'및'static_cast'는 멤버 함수에 대한 포인터가 포인터가 아니기 때문에 작동하지 않습니다 (예, 끔찍한 이름입니다). –

+0

정적 캐스트에 관한, 나는 정적 멤버 함수를 구현할 수 있고이 포인터 주위를 명시 적으로 전달할 수 있다고 생각했습니다. – NoahR

답변

12

, 다음 할 것 캐스팅 : (p->*registered)(0)

참조 : (실제로 파생를 가리키는 제공 )

class Derived : public Base 
{ 
    Derived() { 
     registerPrepFn(static_cast<PrepFn>(&Derived::derivedPrepFn)); 
    }; 

    void derivedPrepFn(int n) {}; 

} 

Base* p 정상적으로 호출 작업 예제는 http://ideone.com/BB9oy입니다.

+0

글쎄, 난 그냥 오류 메시지를 억제하고 싶지 않아요. 이것이 기능적일까요? – NoahR

+0

@NoahR : 예, 작동합니다 (굵은 글씨체로 표시). – jpalecek

+1

표준에서는 이러한 변환에 대해 다음과 같이 말합니다. "클래스 B가 원래 멤버를 포함하거나 클래스를 포함하는 클래스의 기본 또는 파생 클래스 인 경우 원래 멤버, 결과 멤버에 대한 포인터는 원래 멤버를 가리키고 그렇지 않으면 캐스트 결과가 정의되지 않습니다. " 나는 그러한 캐스팅이 OP가 원했던 것을하지 않거나 최악의 경우 유용한 가치를 창출하지 못한다는 것을 두려워한다. –

0

이는 OOP에 사용할 수 없습니다. 동작 전환은 객체 생성시 객체의 클래스를 다형 화하여 수행됩니다.

개체 생성 후 동작 전환이 필요한 경우 동적 동작을 다른 다형성 클래스 집합으로 리팩토링하고 올바른 동작을 사용하여 클래스 인스턴스에 "포인터"를 보유 할 수 있습니다. Google에 "데코레이션 클래스"소프트웨어 패턴을 제공해주세요. 당신이 필요로하는 모든 오류 메시지를 치는 경우

관련 문제