0

멤버 함수 포인터를 가져 오는 데 문제가 있습니다 (가능한 작업이 가능한지 여부를 모르겠습니다). 멤버 변수 (다른 클래스의 비 정적 함수에 대한 포인터)를 설정하고 해당 함수를 호출하려고합니다. 그런 다음 다른 파생 클래스의 다른 멤버 함수로 설정하여 호출 할 수 있기를 원합니다. 2 개의 파생 클래스는 아래의 템플릿에 의해 생성됩니다. 이 문제를 해결할 수 있습니까? 그렇다면 무엇을 잘못하고 있습니까?C++ 포인터를 사용하여 비 정적 멤버 함수

class A { } ; 
class B { } ;  

class BaseClass { 
public: 
    virtual void log() { 
     std::cout << "Log BaseClass." << std::endl ; 
    } 
}; 

template <class T> 
class TVector : public BaseClass { } ; 

template <int N> 
class DTCA : public TVector <A> { 
public: 
    virtual void log() { 
     std::cout << "Log DTCA." << std::endl ; 
    } 
} ; 

template <int N> 
class DTCB : public TVector <B> { 
public: 
    virtual void log() { 
     std::cout << "Log DTCB." << std::endl ; 
    } 
} ; 

class Container { 
public: 
    DTCA <5> dtca ; 
    DTDB <10> dtcb ; 
    void (BaseClass::*log)() ; 
} ; 

내가 이전 부분에서 실수가 있었다 가정 : 그것은 실수의 전체이기 때문에

// Forward declare these, their implementation is irrelevant to the question 
class A; 
class B; 

// declare a base class that contains a function log() that we want to call 
class BaseClass { 
    public: 
     BaseClass() {} 
     virtual ~BaseClass() {} 

     virtual void log() {} // want to call this via function pointers 
}; 

//Using a template means we don't have to specify the type in the vector 
template<class T> 
class TemplateVectorOfBaseClass : public BaseClass { 
    protected: 
     std::vector<T> peripherals;  
} 

// this specific implementation does stuff using Class A 
template <int randomTemplateParameter> 
class DerivedTemplateClassThatDoesStuffWithAs : public BaseClass 
    public: 
     DerivedTemplateClassThatDoesStuffWithAs() : TemplateVectorOfBaseClass<A>() {} 
     void log() {do_something_here_involving_As();} 
     int i[randomTemplateParameter]; 
}; 

// this specific implementation does stuff using Class B 
template <int randomTemplateParameter> 
class DerivedTemplateClassThatDoesStuffWithBs : public BaseClass 
    public: 
     DerivedTemplateClassThatDoesStuffWithBs() : TemplateVectorOfBaseClass<B>() {} 
     void log() {do_something_here_involving_Bs();} 
     float f[randomTemplateParameter]; 
}; 

// Class that contains both templates as member variables  
class ContainerClass { 
    public: 
     ContainerClass(); 

     DerivedTemplateClassThatDoesStuffWithAs dtca<5>; 
     DerivedTemplateClassThatDoesStuffWithBs dtcb<10>; 

     void (BaseClass::*log)(); // pointer to member function log() 
    } 

// usage 
ContainerClass cc; 

cc.container.log = &dtca.log; 
cc.*log(); // should call vectorContainingAs.log() 

cc.container.log = &dtcb.log; 
cc.*log(); // should call vectorContainingBs.log() 
+2

'class ContainerClass {public : ContainerClass container;'. 어떻게 이것이 컴파일 될 수 있습니까? –

+0

귀하의 예는 아직 명확하지 않습니다. cc. * log()는 의미가 없습니다. "cc"객체에 대해 "cc.log"가 가리키는 함수를 실행하려고합니까? 아니면 당신이 dtca 개체를 상대로 달리기를 의도 했습니까? – MerickOWA

+0

비 정적 함수에 대한 포인터는 사용할 수 없습니다. – dari

답변

1

정말 그래서 여기에 그것은 단순화 된 버전으로 작동해야하는 방법은, 코드에 의존 할 수 없다 불량 복사/붙여 넣기로 인해

int main() { 
    Container cc ; 
    cc.log = &BaseClass::log ; // Store the log member function into cc.log 

    (cc.dtca.*cc.log)() ; // Call it on dtca 
    (cc.dtcb.*cc.log)() ; // Call it on dtcb 

    return 0 ; 
} 

출력 :

로그 DTCA는 주로 틀린 부분은 포인터 방법을 할당하는 방법 및 개체의 메소드를 호출 할 수있는 방법이었다.

로그 DTCB.

ISO C++ 멤버 함수에 대한 포인터를 형성하기 위해 결합 된 멤버 함수의 주소를 복용 금지한다 :

당신은 인스턴스에서 메서드의 주소를받을 수 없어, 당신은 같은 것을 얻을 것이다.

그래서 당신은 당신의 변수의 타입이기 때문에 (BaseClass::*)() 당신은 BaseClass에서 직접 수행해야, 방법에 주소를 가지고. 그런 다음 인스턴스 BaseClass 또는 파생 클래스를 사용하여 호출해야합니다.

+0

감사합니다. 대단히 감사합니다. – John

관련 문제