2009-04-14 7 views
4

그 중 무엇이 요점입니까?
나는 결코 그것들을 사용하지 않았으며, 나는 그것들을 전혀 사용할 필요가 없다.
나는 그 (것)들에 관하여 무언가를 놓치고 또는 꽤 쓸모 없다?

편집 : 나는 ... 그래서 그들에 대한 설명이 필요할 수 있습니다,C++의 멤버 연산자에 대한 포인터 포인터

+0

http://stackoverflow.com/questions/654853/why-would-one-use-function-pointers-to-member-method-in-c 찾으시는 항목은 무엇입니까? – nevets1219

+0

아니요, 더 구체적으로. * 및 -> * 연산자. – DeadHead

+0

나는 그가 회원 운영자 (예 : 운영자 +)에 대한 포인터에 대해 이야기하고 있다고 생각한다. –

답변

10

PMF (멤버 함수 포인터)를 제외하고, 통상의 정적 함수 포인터처럼 비 정적 멤버 함수 지정 될 this 객체를 필요로하기 때문에 상기 PMF 호출 구문 (.* 또는 ->*) this 개체를 지정할 수 있습니다 (왼쪽에 있음).

#include <complex> 
#include <iostream> 
#include <map> 
#include <stack> 
#include <stdexcept> 
#include <string> 

namespace { 
    using std::cin; using std::complex; using std::cout; 
    using std::invalid_argument; using std::map; using std::stack; 
    using std::string; using std::underflow_error; 

    typedef complex<double> complexd; 
    typedef complexd& (complexd::*complexd_pmf)(complexd const&); 
    typedef map<char, complexd_pmf> opmap; 

    template <typename T> 
    typename T::reference top(T& st) { 
     if (st.empty()) 
      throw underflow_error("Empty stack"); 
     return st.top(); 
    } 
} 

int 
main() 
{ 
    opmap const ops{{'+', &complexd::operator+=}, 
        {'-', &complexd::operator-=}, 
        {'*', &complexd::operator*=}, 
        {'/', &complexd::operator/=}}; 

    char op; 
    complexd val; 
    stack<complexd> st; 

    while (cin >> op) { 
     opmap::const_iterator opit(ops.find(op)); 
     if (opit != ops.end()) { 
      complexd rhs(top(st)); 
      st.pop(); 
             // For example of ->* syntax: 
      complexd& lhs(top(st));  // complexd* lhs(&top(st)); 
      (lhs.*opit->second)(rhs); // (lhs->*opit->second)(rhs); 
      cout << lhs << '\n';  // cout << *lhs << '\n'; 
     } else if (cin.unget() && cin >> val) { 
      st.push(val); 
     } else { 
      throw invalid_argument(string("Unknown operator ") += op); 
     } 
    } 
} 

[Download]

: 여기

는 (: (lhs.*opit->second)(...)을하고 PMF, &class::func 작성을위한 신택스 사용되고 .* 연산자를 "마법"라인을 주) 사용 PMFs의 예

실제 숫자 대신 복소수를 사용하는 간단한 RPN 계산기입니다 (대부분 std::complex은 과부하 연산자가있는 클래스 유형이기 때문에). 나는 이것을 clang으로 테스트했다. 귀하의 마일리지는 다른 플랫폼에 따라 다를 수 있습니다.

입력은 (0,1)이어야합니다. 공백은 선택 사항이지만 가독성을 위해 추가 할 수 있습니다.

+0

코드에 _no_ 오류 검사가 있지만 어쨌든 아이디어를 얻길 바랍니다. :-D –

+0

그래, 이치에 맞다. 예를 들어 주셔서 감사합니다. – DeadHead

+0

빈 스택에 segfaults를 가져 오는 것이 실제로 나를 괴롭히기 때문에 실제로는 오류 검사를 추가하기 위해 내 버전을 업데이트했습니다. :-) –

4

바인딩을 그들에 대해 많이 알고하지 않는 함수에 대한 포인터는 다양한 상황에서 매우 유용하다. 기본적으로 함수를 변수로 참조 할 수 있으므로 런타임에 함수를 호출 할 함수를 선택할 수 있습니다.

하나의 용도는 "콜백"입니다. 얼마 동안 백그라운드 프로세스가 작동하기를 원한다고 말하면, 완료되면 (GUI를 업데이트 할 수 있도록) 알려주십시오. 그러나 때로는이 백그라운드 프로세스가 하나의 메서드를 호출하기를 원할 때가 있습니다. 때로는 다른 메서드를 호출하기를 원합니다. 이 백그라운드 프로세스의 두 가지 버전을 작성하는 대신 백그라운드 프로세스가 "콜백"할 함수에 대한 포인터를 수신하도록 작성할 수 있습니다. 그런 다음 프로세스가 완료되면 처음부터 주어진 기능을 호출합니다.

기본적으로 호출 할 메서드를 결정할 때 융통성을 더 많이 가질 수 있습니다. 그런 식으로 다형성과 매우 유사합니다. 사실, C++은 다형성을 돕기 위해 함수 포인터를 사용합니다 (각 클래스의 함수에 대한 다른 포인터를 저장하여).

1

질문을 올바르게 이해하면. 왜 안돼?

struct test 
{ 
    test* operator->() 
    { 
     std::cout << "test::operator->"; 
     return this; 
    } 
}; 

test tt; 
boost::bind(&test::operator ->, _1)(tt); 
+0

제 질문은 그 운영자가 무엇인지에 관한 것이었고 운영자를 사용하는 대안은 무엇인지에 관한 것이 었습니다. – DeadHead