2017-02-16 18 views
2

가상 함수의 동작 예를 살펴 보겠습니다. 이 테스트 코드가 주어지면 그 동작에 대해 몇 가지 질문이 있습니다.가상 함수 서명 불일치 및 그 동작

class A 
{ 
public: 
    A(int x) 
    { 
     cout << "In A Constructor" << endl; 
     print(); 
    } 
    ~A(){ 
     cout << "In A Destructor" << endl; 
     delete _val; 
    } 
    virtual void print() { cout << "A." << endl; } 
private: 
    char* _val; 
}; 

class B: public A 
{ 
public: 
    B(int x, int y) : A(x) 
    { 
     _dVal = new char[y]; 
     cout << "In B Constructor 1" << endl; 
     print(); 
    } 
    B() : A(0) 
    { 
     _dVal = new char[1]; 
     cout << "In B Constructor 2" << endl; 
     print(); 
    } 
    ~B(){ 
     cout << "In B Destructor" << endl; 
     delete _dVal; 
    } 
    void print() { cout << "B" << endl; } 
private: 
    char* _dVal; 
}; 

int main(int argc, char** argv) { 
    A* p1 = new B(); 
    p1->print(); 
    delete p1; 
    return 0; 
} 

출력은 :

클래스 A가 가상 함수로 나타내는 단 하나이고, 그것은 역 참조 (호출되는 경우 인쇄 클래스 B 요구되는 이유
In A Constructor 
A. 
In B Constructor 2 
B 
B 
In A Destructor 

1) ->)? 2) 생성자가 실제로 호출되는 경우 B의 소멸자가 호출되지 않는 이유는 무엇입니까?

+1

함수가 기본 클래스에서 가상 인 경우 모든 파생 클래스에서도 가상 함수입니다. 소멸자에게도 마찬가지입니다. –

+1

질문 당 한 가지 질문하십시오. –

답변

4

1) 클래스 A가 가상 함수로 표시하고 역 참조 (->)로 호출되는 경우 클래스 B에 대해 인쇄가 호출되는 이유는 무엇입니까?

가상 기능이하는 일입니다. p1 포인터는 A* 유형이지만 사실 B 유형의 객체를 가리키고 있습니다. 그리고이 동적 바인딩은 파생 클래스가 기본 클래스에 대한 포인터 또는 참조를 사용하여 처리 될 때만 발생합니다.

또한 파생 클래스의 재정의 함수는 virtual (키워드 virtual이 선언에 사용되었는지 여부에 관계없이)입니다.

2) 생성자가 실제로 호출되는 경우 B의 소멸자가 호출되지 않는 이유는 무엇입니까?

당신이 virtual destructor으로 기본 클래스의 소멸자 (즉 A::~A)를 선언하지 않는 때문에 B의 소멸자가 호출되지

. 이 경우 동작은 정의되지 않습니다. B의 생성자는 B을 명시 적으로 new B()으로 구성하기 때문에 호출됩니다.

+0

흥미 롭습니다. 동작이 정의되지 않았기 때문에 클래스 B의 _dVal이 oprhan이되어 메모리 누수가 발생합니다. – w0ffen

+0

@ user49096 관찰 한 결과에서 네. 그것은 미정이기 때문에 무엇이든 가능합니다. – songyuanyao

+0

@ user49096 "_ 동작이 정의되지 않았기 때문에 의미가 있습니까?"아니오, 일어나는 일이 정의되지 않았거나 정의되지 않았거나 알 수 없음을 의미합니다. – curiousguy