2017-01-12 5 views
1

이 코드비 가상 오버로드 된 멤버 함수

#include <iostream> 

struct A { 
    int one() { 
    std::cout << "oneA" << std::endl; 
    } 
    int devone() { 
    one(); 
    } 
}; 

struct B : A { 
    int one() { 
    std::cout << "oneB" << std::endl; 
    } 
}; 
int main() { 
    B b; 
    b.devone(); 
} 

인쇄 oneA

나는 이유를 이해하지 않습니다. 가상 기능을 사용하는 경우 oneB이 인쇄되지만 위의 코드 예제에서는 그렇지 않은 이유를 알고 있습니다. 포인터 또는 참조가 사용되지 않습니다. 왜 함수 가상을 선언해야합니까?

+0

실제로 포인터가 있습니다. 그것은 단지 당신에게서 숨겨져 있습니다. 모든 멤버 함수에는'this' 포인터가 있음을 기억하십시오. – NathanOliver

+2

'A :: devone' 내부의'this'의 타입은'A *'이므로'A :: one'이 호출됩니다. – nwp

답변

2

포인터 또는 참조가 사용되지 않아서 함수 가상을 선언해야하는 이유는 무엇입니까?

int A::devone() { 
    one(); 
} 

과 같다 :

int A::devone() { 
    this->one(); 
} 

그래서 포인터를 사용, 당신은 virtual 기능을 사용할 필요가 런타임에 적절한 기능을 해결하기 위해

당신은,이 코드를 잘못.

1

one을 가상으로 선언하지 않으면 A vtable에 항목이 없습니다. A에 vtable 항목이 없으면 해당 항목은 자신 만 알고있는 one이라는 것을 의미합니다. 따라서 oneA::devone에서 호출하면 논리적 인 유일한 기능은 입니다.A::one입니다.

1

A :: devone()을 호출하면 A : one()이 호출되므로 "oneA"가 출력됩니다.
A :: one()은 가상이 아니기 때문에 B 인스턴스가 있어도 기본 A 클래스 one() 메서드가 호출됩니다. 당신이 B 클래스에

int devone() { 
    one(); 
    } 

를 추가하는 경우

는 B : 한() 메서드를 대신 호출 할 것입니다.