2013-05-13 3 views
1

나 C++에 다음 코드 한 벡터에서 작동 :오해 가상 기능

#include <iostream>; 
#include <vector>; 

class A 
{ 
public: 
    A(int n = 0) : m_n(n) { } 

public: 
    virtual int value() const { return m_n; } 
    virtual ~A() { } 

protected: 
    int m_n; 
}; 

class B 
    : public A 
{ 
public: 
    B(int n = 0) : A(n) { } 

public: 
    virtual int value() const { return m_n + 1; } 
}; 

int main() 
{ 
    const A a(1); 
    const B b(3); 
    const A *x[2] = { &a, &b }; 
    typedef std::vector<A> V; 
    V y; 
    y.push_back(a); 
    y.push_back(b); 
    V::const_iterator i = y.begin(); 

    std::cout << x[0]->value() << x[1]->value() 
     << i->value() << (i + 1)->value() << std::endl; 

    system("PAUSE"); 

    return 0; 
} 

컴파일러 반환 된 결과 : 1413

내가 올바른 결과는 1414이 될 것이라고 생각하기 때문에 나는 조금 혼란 스러워요 (함수 가상으로서). 이 프로그램의 행동을 어떻게 설명합니까?

+3

'# include '지시문의 끝에';'를 쓰지 마십시오. – Fabien

+0

@Fabien 나는 컴파일 된 프로그램에 놀랐다. – imulsion

답변

6

당신은 slicing 개체입니다. 다형성을 얻으려면 pointer 또는 reference 중 하나를 사용해야합니다. 이 예는 원래 예에 최대한 가깝게 유지하고 당신이 원하는으로 pointer이 역할을 사용하여 : 객체 슬라이스 여기에 어떻게 작동하는지

const A a(1); 
const B b(3); 

typedef std::vector<const A*> V; 
V y; 
y.push_back(&a); 
y.push_back(&b); 
V::iterator i = y.begin(); 

std::cout << (*i)->value() << std::endl ; 
++i ; 
std::cout << (*i)->value() << std::endl ; 
+0

고마워. 이제는 분명합니다. –

4

간략하게 표시하려면 :

const A a(1); 
const B b(3); 
std::vector<A> y; // so y contains objects of type A 

y.push_back(a); // y[0] is copy-constructed from a 
y.push_back(b); // y[1] is copy-constructed from b 

참고 그 두 push_back을에 자동으로 생성 된 A::A(const A&) 복사 생성자를 통해 항상 A이 생성됩니다.

참고도 B는-A 것을 b 암시 같은 복사 생성자 내로 A에 캐스팅 전달 될 수있는 말을하는 것입니다A.

그래서, y[1]b에서 복사 한 m_nA의 인스턴스입니다,하지만 가상 함수는 여전히 A::value입니다. B::B 생성자가 초기화 될 때 값을 수정하면, 반환 될 때가 아니라 예상 한 결과가 표시됩니다.