문제

나는 멤버 함수를 정상 함수의 특수한 경우라고 생각하는 데 익숙한데, 멤버 함수는 '이'포인터, 즉 멤버가 기능하는 객체에 대한 매개 변수 목록의 시작 부분에 추가 매개 변수가 있습니다. 행동해야합니다. 나는 과거에 Boost :: 기능을 사용했지만 아무런 문제에 직면하지 않았습니다.

boost::function f<(void)(MyObject*, int, int)> = &MyObject::method_that_takes_two_ints;

그러나 나는 멤버-기능 포인터에 대한이 구문을 보았다.

void (MyObject::*f)( int, int ) = &MyObject::method_that_takes_two_ints;

이 구문에서 '이'매개 변수는 보이지 않습니다. 그것은 후드 아래의 후드 포인터-멤버-흡인이 실제로 별도의 짐승인지 궁금해했으며, 그 부스트는 나에게 세부 사항을 돌보고있었습니다.

표준은 '이'매개 변수의 배치에 대해 무엇을 지시합니까? 아마도 내 컴파일러에서 추가 '이'인수가 먼저오고 다른 컴파일러에서는 끝에있을 수 있습니까? 내 생각 방식이 내 컴파일러 (GCC4, vs2005)와 일치한다는 것이 운이 좋습니까? 포인터 투 선원 기능은 항상 추가 매개 변수를 갖춘 특별한 포인터 간 기능의 특별한 경우입니까, 아니면 컴파일러가 다르게 구현할 수 있습니까?

도움이 되었습니까?

해결책

표준은 어디에 있는지에 대해 아무것도 말하지 않습니다 this 포인터를 배치해야하며, 실제로 회원 기능에 대해 다른 통화 규칙을 사용하는 것이 일반적입니다. (따라서 '이'포인터는 단순한 첫 번째 인수가 아니라 실제로 첫 번째 Arg와는 다른 위치에 저장되어 있습니다).

특히 MSVC를 사용합니다 thiscall 회원 기능을위한 컨벤션 호출 및 stdcall 다른 곳.http://www.hackcraft.net/cpp/mscallingconventions/#thiscall 그들 사이의 차이점을 설명하지만 주목하십시오 thiscall 저장 this 포인터 ECX 등록하십시오 stdcall 백화점 모두 스택의 매개 변수.

당신은 그것들을 완전히 뚜렷한 유형으로 취급하는 것이 좋습니다. 멤버 함수에 대한 포인터는 다음과 같습니다 ~ 아니다 추가 매개 변수가있는 함수에 대한 포인터 일뿐입니다.

다른 팁

그만큼 this 포인터는 멤버에 대한 포인터를 따라 저장되지 않습니다 (멤버 함수 포인터는 특별한 경우입니다). 당신이 그냥한다면

void (MyObject::*f)( int, int ) = &MyObject::method_that_takes_two_ints;

그런 다음 저장된 것은 나중에 제공 해야하는 OBJET에서 멤버 기능을 호출 해야하는 정보입니다. 당신이 그것을 호출하려면, 당신은 객체를 따라 전달해야합니다. this 포인터.

MyObject o; (o.*f)(1, 2);

멤버 기능 포인터는 유형 (포인트)이 함수 유형 인 멤버 포인터 일뿐입니다. 표준에 따르면 멤버 기능 포인터는 자체 "멤버 기능 유형"이 없으며이 포인터 유형을 포함 할 수있는 자체 "멤버 기능 유형"이 없다고 말합니다.

int main() {
    typedef void fun() const;
    fun MyObject::*mem_function_ptr = 
        &MyObject::const_method_that_takes_two_ints;
}

fun 이 코드에는 기능 유형이 있습니다. "일반"함수가 가진 유형. 멤버-기능 포인터와 달리 포인터 간 기능은 해당 유형을 가진 함수에 대한 포인터 일뿐입니다.

void foo() { cout << "hello"; }
int main() {
    typedef void fun();
    fun * f = &foo;
}

포인터 투 인원 기능은 해당 함수 유형의 추가 멤버 포인터 레벨을 갖습니다.

에 대해 뭔가 this 포인터 및 그것이 가리키는 객체와 관련된 방법 (기술적이지 않고 이론적 인 것들) :

각 멤버 함수에는 The라는 숨겨진 매개 변수가 있습니다 implicit object parameter 유형이 있습니다 MyObject& 또는 MyObject const& Const 또는 Unconst 멤버 기능이 있는지 여부에 따라 다릅니다. 회원 함수를 켜는 객체, o,,입니다 implied object argument, 매개 변수로 전달됩니다. 멤버 기능이 호출되는 방식을 설명하는 규칙을 구성하는 표준 이론에서 암시 적 개체 매개 변수는 첫 번째 숨겨진 매개 변수입니다. 그것이 개념적이며, 그것이 구현의 실제 사례라는 것을 의미하지는 않습니다. 묵시적 객체 인수는 해당 암시 적 객체 매개 변수에 결합되어 암시 적 변환을 유발할 수 있습니다 (따라서 비정규 개체에서 const 멤버 함수를 호출하는 경우 자격 변환이에서 변환됩니다. MyObject 에게 MyObject const&. 이것이 바로 비 정중 함수를 const 함수보다 더 나은 선택으로 만들지 않습니다. 예를 들어이 코드에서는 다음과 같이 말할 수 있습니다.

struct A {
    operator int() const { return 0; }
};

int main() { 
    A a;
    int i = a; // implicit conversion using the conversion function
}

묵시적 대상 주장 a 유형의 A 유형의 암시 적 개체 매개 변수에 바인딩됩니다 A const&, 그 객체가 this 유형이있는 포인터 A const* 여기. 주목해야 할 중요한 객체 매개 변수는 이론적 구성 일 뿐이며, 멤버 함수 호출 규칙이 어떻게 구성되는지 (그리고 생성자가 포함하지 않는)이 포인터는 실제로 존재한다는 것입니다. this 언제 때문에 포인터입니다 this C ++에는 아직 참조가 없었습니다.

그 문제를 이해하는 데 도움이되기를 바랍니다.

회원 기능 포인터에 대한 훌륭한 기사는 CodeProject 's입니다. 멤버 기능 포인터 및 가장 빠른 C ++ 대의원. 이 기사에서는 간단한 경우의 멤버 기능 포인터가 여러 상속을 가진 가상 멤버 함수 포인터를 통해 설명합니다. 보너스로서, 그것은 정말로 유용 할 수있는 대의원의 구현을 제공합니다.

그렇습니다. 포인터 투 연기와 포인터 대회는 완전히 다른 짐승입니다. 멤버에 대한 포인터는 ->* 또는 .* 운영자. 아니요 this 포인터 투 인원을 만들 때 사용되는 매개 변수 this 멤버에 대한 포인터가 사용될 때 결정됩니다 (왼쪽의 물체 ->* 또는 .*).

포인터 투 인 함수와 포인터 투-멤버 변수 사이에는 포인터 투 관련 함수와 일반 함수 포인터 사이에있는 것보다 포인터 투 관련 변수 사이에 차이가 적을 수 있습니다.

일반적으로 회원 기능과 일반 기능은 완전히 다른 통화 규칙을 가질 수 있으므로 그 사이에 캐스트 할 수 없습니다.

포인터 투회-기능의 크기는 컴파일러를 사용하여 다를 수 있습니다.

쓴대로 주목해야 할 또 다른 사항 오래된 새로운 블로그:

포인터 투회-기능의 크기는 클래스에 따라 변경 될 수 있습니다.

그것들은 확실히 다른 유형이며 당신이하는 모든 가정은 플랫폼/컴파일러에 따라 다릅니다.

이 페이지 수많은 인기있는 컴파일러에 대한 구현 세부 사항을 포함하여 내가 알고 싶었던 것보다 멤버 기능 포인트 구현에 대한 자세한 정보가 있습니다.

모든 질문에 답하기 위해 : 예, 그들은 평범한 포인터와 다른 특별한 포인터입니다. 예, 부스트 :: 기능이 인식합니다.

표준은 콜 스택의 내부 세부 사항에 대해 아무 말도하지 않습니다. 실제로, 많은 컴파일러는 실제 인수 목록에 따라 정수 방해사, 부동 소수점 레지스터 및/또는 스택을 사용할 수 있습니다. '이'포인터는 더 특별한 경우입니다.

부스트 :: 기능은 내부적으로 두 개의 코드 경로를 사용하여이를 해결합니다. 두 경우에 대한 통화 스택을 검사하여이를 볼 수 있습니다. Boost :: 함수가 멤버 함수에 대한 포인터를 저장하면 Operator ()가 인수 목록을 분할합니다. 첫 번째 인수는 멤버 함수가 나머지 인수와 함께 호출되는 객체로 사용됩니다.

다른 모든 사람의 답변을 보충하기 위해 Boost.function은 멤버 기능 포인터에서 할당 연산자를 전문화하여 통과했을 때 감지 할 수 있도록합니다. 해당 기능을 호출하면 내부적으로 멤버 기능 포인터를 호출하는 적절한 방법으로 재 해석됩니다 ((obj->*fun)(args)).

이 링크가 매우 흥미로울 수 있다고 생각합니다.

http://www.parashift.com/c++-faq-lite/pointers-to-members.html

포인터 투 멤버에 대해 알고 싶은 모든 것에 대한 아주 좋은 설명입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top