2017-02-19 11 views
2

는 다음과 같은 예를 생각해파생 클래스의이 포인터를 기반으로 멤버 함수를 찾는 방법은 무엇입니까?

struct B1 { 
    void f() { 
     this->g(); 
     std::cout << this << std::endl; 
    } 
    void g() { 
     std::cout << "B1::g" << std::endl; 
    } 
}; 

struct B2 { 
    void f() { 
     this->g(); 
     std::cout << this << std::endl; 
    } 
    void g() { 
     std::cout << "B2::g" << std::endl; 
    } 
}; 

struct C: B1, B2 { 
    void f() { 
     B1::f(); 
     B2::f(); 
     std::cout << this << std::endl; 
    } 
    void g() { 
     std::cout << "C::g" << std::endl; 
    } 
}; 

int main() { 
    C c; 
    c.f(); 
    return 0; 
} 

나를 위해, 출력은 다음과 같습니다

B1::g 
0x7fffa11436b7 
B2::g 
0x7fffa11436b7 
0x7fffa11436b7 

우리가 B2::f에 초점을 보자. 결과에서 볼 수 있듯이 B2::f 안에 thisC 유형의 개체 시작 부분을 가리 킵니다. 그렇다면 this->g()은 어떻게 정확히 B2::g()으로 해결 되었습니까?

+0

다른 무엇가 해결 것입니다 (막 3 구조체에 virtual void g()void g()를 교체하려고) C::g 전화 때문에 g이 가상했다 다르게하면 갈 것? 'B2 :: g()'보다 * 다른 *이 될 것이라고 기대하십니까? 실제 호출의 메커니즘이 언어 표준에 의해 정의되지는 않지만 해결 방법은 분명합니다. 그럼에도 불구하고 이것을 asm으로 컴파일하면'this-> g()'가'this' (레지스터 최적화가 명백히 잠재적 인)와'B :: g의 직선 - 호출 (invoke))'. 결국,'g()'는 가상이 아닙니다. – WhozCraig

+0

포인터 값이 오도 된 것입니다. 세 개의 구조체 각각에 데이터 멤버를 추가하고 다시 시도하십시오. –

답변

0

여기에 가상 기능이 없습니다. 따라서 g 회원 함수를 호출하면 B1::f에서 으로 전화 할 것입니다. 정의는B1::g입니다. 상황이 참으로 모든 f 기능