문제

다음 C++코드:

class A
{
public:
      virtual void f()=0;
};


int main()
{
     void (A::*f)()=&A::f;
}

면 나는 추측이라고 말하고 싶&A::f 이 컨텍스트에서는 의미는"주의 구현 f()",없으므로 명시적인 분리 사이의 포인터를 정기적인 멤버의 기능과 가상 구성원 기능입니다.그 때문에 구현되지 않았다 f(),는 것이 컴파일에 오류가 있습니다.그러나,그것은 아닙니다.

그뿐만이 아닙니다.다음 코드:

void (A::*f)()=&A::f;
A *a=new B;            // B is a subclass of A, which implements f()
(a->*f)();

이 실제로 부 B:f.

그것은 어떻게 일어나는가?

도움이 되었습니까?

해결책

회원 기능 포인터에 대한 정보가 너무 많습니다. 기사가 실제로 C ++에서 대의원을 구현하는 것에 관한 것이기 때문에 IIRC는 "잘 행동 한 컴파일러"아래의 가상 기능에 대한 몇 가지 사항이 있습니다.

http://www.codeproject.com/kb/cpp/fastdelegate.aspx

짧은 대답은 컴파일러에 따라 다르지만, 한 가지 가능성은 멤버 기능 포인터가 가상 호출을하는 "펑크"함수에 대한 포인터를 포함하는 구조물로 구현 될 가능성이 있다는 것입니다.

다른 팁

표준이 그것이 어떻게 일어나야하는지 말하기 때문에 작동합니다. GCC로 일부 테스트를 수행했으며 가상 함수에 대해 GCC는 해당 기능의 가상 테이블 오프셋을 바이트로 저장합니다.

struct A { virtual void f() { } virtual void g() { } }; 
int main() { 
  union insp { 
    void (A::*pf)();
    ptrdiff_t pd[2]; 
  }; 
  insp p[] = { { &A::f }, { &A::g } }; 
  std::cout << p[0].pd[0] << " "
            << p[1].pd[0] << std::endl;
}

그 프로그램 출력 1 5 -이 두 기능의 가상 테이블 항목의 바이트 오프셋. 그것은 따릅니다 이타늄 C ++ ABI, 그것을 지정합니다.

나는 완전히 확실하지 않습니다,그러나 내 생각에 그냥 일정한 다형성 동작입니다.내 생각에는 &A::f 실제로 의미의 주소는 함수 포인터에서 클래스의 vtable,그리고 당신은 왜 못하고 컴파일러에 오류가 있습니다.공간에서 vtable 은 여전히 할당하고,그 위치에 당신은 실제로 다시 얻.

이것은 감지기 때문에 파생 클래스는 기본적으로 덮어쓰기는 이러한 값으로 포인터를 자신의 기능입니다.이런 이유 (a->*f)() 에서 작동하는 두 번째 예제 f 를 참조하 vtable 서 구현된 파생된 클래스입니다.

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