2009-06-13 7 views
38
class Foo { 
public: 
    Foo() { do_something = &Foo::func_x; } 

    int (Foo::*do_something)(int); // function pointer to class member function 

    void setFunc(bool e) { do_something = e ? &Foo::func_x : &Foo::func_y; } 

private: 
    int func_x(int m) { return m *= 5; } 
    int func_y(int n) { return n *= 6; } 
}; 

int 
main() 
{ 
    Foo f; 
    f.setFunc(false); 
    return (f.*do_something)(5); // <- Not ok. Compile error. 
} 

어떻게 작동합니까?비 정적 멤버 함수에 대한 C++ 함수 포인터 (클래스 멤버)

+1

'func_x' 및'func_y' 정적 함수는 그와 같이 표시되지 않습니까? –

답변

31

당신이 원하는 선은

return (f.*f.do_something)(5); 

(나는 그것을 시도했습니다 즉, 컴파일)입니다 어디에 do_something 값을 에서 얻으려면. 그러나 우리는 함수를 호출 할 때 여전히이 포인터가 될 객체를 줄 필요가 있습니다. 그렇기 때문에 "f."이라는 접두어가 필요합니다.

+8

기술적으로 "f.do_something"은 포인터를 반환하고 ". *"연산자는 클래스에 대한 포인터 기능을 호출합니다. –

+0

그래서'return (f. * Foo :: do_something (5)')도 동작해야한다고 가정합니다. – ThomasMcLeod

+1

@ThomasMcLeod 그렇지 않습니다. –

0

시도해보십시오 (f. * do_something) (5);

"*f.do_something"포인터 자체 ---을 의미한다 "f는"우리에게 -

35
class A{ 
    public: 
     typedef int (A::*method)(); 

     method p; 
     A(){ 
      p = &A::foo; 
      (this->*p)(); // <- trick 1, inner call 
     } 

     int foo(){ 
      printf("foo\n"); 
      return 0; 
     } 
    }; 

    void main() 
    { 
     A a; 
     (a.*a.p)(); // <- trick 2, outer call 
    } 
+3

+1 두 트릭을 위해서 –

+0

투독, 두 번째로 당신의 포스트를 지나친 후에 나는 당신이 옳은 대답 (트릭 2)을 준 것을 깨달았습니다. 감사. – Girish

+0

코드가 작동하지 않습니다. 복사/붙여 넣기를하고 컴파일을 시도합니다. test_function_pointer_2.C : 생성자 'A :: A()': test_function_pointer_2.C : 7 오류 : 'int (A ::)()'유형의 인수가 'int (A :: *)() ' – user180574

-4

정적 멤버 함수를 사용하여 정적 멤버가 아닌 클래스를 호출 할 수도 있다고 생각합니다.

+1

이것은 불가능합니다. "클래스 선언에서 데이터 멤버를 수정할 때 static 키워드는 클래스의 모든 인스턴스에서 멤버의 복사본 하나를 공유하도록 지정합니다. 클래스 선언에서 멤버 함수를 수정하면 ** 정적 키워드는 함수가 액세스하도록 지정합니다 정회원 만 **. " [MSDN 참조] (http://msdn.microsoft.com/en-us/library/s1sb61xd(v=80) .aspx) – ForceMagic

+0

잘 생성자를 통해 모든 인스턴스의 목록을 유지하고 호출 할 수 있습니다 그것은 모든 경우에 대한 것이지만 그것은 다소 이상한 아이디어라고 생각합니다 : p –

3
class A { 
    int var; 
    int var2; 
public: 
    void setVar(int v); 
    int getVar(); 
    void setVar2(int v); 
    int getVar2(); 
    typedef int (A::*_fVar)(); 
    _fVar fvar; 
    void setFvar(_fVar afvar) { fvar = afvar; } 
    void insideCall() { (this->*fvar)(); } 
}; 

void A::setVar(int v) 
{ 
    var = v; 
} 

int A::getVar() 
{ 
    std::cout << "A::getVar() is called. var = " << var << std::endl; 
    return var; 
} 

void A::setVar2(int v2) 
{ 
    var2 = v2; 
} 

int A::getVar2() 
{ 
    std::cout << "A::getVar2() is called. var2 = " << var2 << std::endl; 
    return var2; 
} 

int main() 
{ 
    A a; 
    a.setVar(3); 
    a.setVar2(5); 

// a.fvar = &A::getVar; 
    a.setFvar(&A::getVar); 
    (a.*a.fvar)(); 

    a.setFvar(&A::getVar2); 
    (a.*a.fvar)(); 

    a.setFvar(&A::getVar); 
    a.insideCall(); 

    a.setFvar(&A::getVar2); 
    a.insideCall(); 

    return 0; 
} 

나는 Nick Dandoulakis의 대답을 확장했다. 고맙습니다.

멤버 함수 포인터를 클래스 외부에서 설정하는 함수를 추가했습니다. 멤버 함수 포인터의 내부 호출을 표시하기 위해 외부에서 호출 할 수있는 또 다른 함수를 추가했습니다.

+0

코드 블록을 게시하기보다는이 코드가 문제를 해결하는 이유를 설명하십시오. 설명이 없으면 이것은 대답이 아닙니다. –

+0

@MartijnPieters 나는 그것이 Nick Dandoulakis 대답에서 연장되었다고 썼다. 그것은 거기에서 설명되었다. 나는 어쩌면 내가 다른 방식으로해야 할 stackoverflow에 새로운입니다. –

+0

글쎄, 당신은 당신이 어떻게 바꿨는지 설명 할 수 있습니다. –

0
#include<iostream> 
using namespace std; 

class A { 

public: 
    void hello() 
    { 
     cout << "hello" << endl; 
    }; 

    int x = 0; 

}; 


void main(void) 
{ 

    //pointer 
    A * a = new A; 
    void(A::*pfun)() = &A::hello; 
    int A::*v1 = &A::x; 

    (a->*pfun)(); 
    a->*v1 = 100; 
    cout << a->*v1 << endl << endl; 

    //----------------------------- 
    A b; 
    void(A::*fun)() = &A::hello; 
    int A::*v2 = &A::x; 

    (b.*fun)(); 
    b.*v2 = 200; 
    cout << b.*v2 << endl; 

} 
관련 문제