2011-07-01 2 views
1

맞쳐 예를 제공하여 내 문제를 설명 :가상 함수가 상속에서 이상하게 작동합니까?

#include <iostream> 

class PC 
{ 
public: 
    PC():Data(0) 
    { 
    } 
    virtual void display() 
    { 
     std::cout<<"The data is :"<<Data<<std::endl; 
    } 
protected: 
    int Data; 
}; 

class SmartPC:private PC 
{ 
public: 
    SmartPC():PC() 
    { 
    } 
    void convert() 
    { 
     PC* temp=static_cast<PC*>(this); 
     temp->display(); 
    } 
    void display() 
    { 
     std::cout<<"The data is (in bb):"<<a<<std::endl; 
    } 
}; 

int main() 
{ 
    SmartPC SmrtPC; 
    PC* miniPC= static_cast<PC*>(&SmrtPC); 
    SmrtPC.convert(); 
} 

를 스콧 마이어스에 따르면 static_cast<PC*>(this);이 SmartPC의 임시 기본 복사본을 생성합니다. 그러나 temp->display();은 파생 클래스의 display() 함수를 실행했습니다. 왜 이렇게이다? 객체가 이제 완전히 SmartPC베이스의 복사본이기 때문에 base의 display()의 함수를 실행하면 안됩니까?

또 다른 질문은 내가 선을 temp->data; 기능 convert()에 추가하면, 그것은 PC::Data가 보호하지만 SmartPC 즉 파생 클래스 범위에서 액세스하고 말한다, 그래서 왜 작동하지 않는 이유는 무엇입니까?

도움을 주시면 감사하겠습니다.

+1

마이어스가 그 말을 한 것에 대한 인용문을 제공해 주실 수 있습니까? 아마도 당신은 그를 오해했을 것입니다. –

답변

5

scott meyers : static_cast<PC*>(this);에 따르면 SmartPC의 임시 기본 복사본이 생성됩니다. 하지만 temp->display();display() 파생 클래스의 함수를 실행 한 이유는 무엇입니까? 객체가 이제 완전히 SmartPC베이스의 복사본이기 때문에베이스의 display()의 기능을 실행해야합니다.

없음 복사본이 생성되지 않습니다, 당신은 단지 포인터을 을 캐스팅.

클래스 함수의 "올바른"버전을 호출하는 포인터의 결과를 통해 virtual 함수를 호출하기 때문에

다형성 (SmartPC *있는 객체의 동적 유형에 따라).

대신, display하지 virtual했다 경우, 기본 클래스의 버전이 호출 할 수있는 버전을 확인하기 위해 포인터의 정적 유형의 비 virtual 방법에 대한 때문에, 호출 된 것이다.

당신이 한 경우 대신 것을


공지 사항 (virtual 기능을 상속 재정의하는 경우 display이 명시 적으로 지정 아닌 경우에도 SmartPC에도 virtual되면, virtual 한정자는 암시) :

PC temp(*this); 

실제로는 사본을 만들었을 것입니다. 현재 객체의, 객체로 "분리 된" 유형은 PC입니다. 이를 "객체 조각화"라고하며 복사 생성자 PC에 의해 수행됩니다. 대부분 이것은 원하지 않는 동작입니다 (파생 클래스의 객체는 실제로 기본 클래스의 객체가되고 일부는 예상대로 다형성이 작동하지 않기 때문에).


또 다른 질문은 내가 temp->data;convert() 기능에 라인을 추가하는 경우, 그것은 PC::Data가 보호하지만 난 SmartPC 즉 파생 클래스 범위에서 액세스하고 말한다, 그래서 왜 작동하지 않는 이유는 무엇입니까?당신은 당신이 다른 객체의 private 멤버에 액세스하려는 temp->data에 액세스하려고 할 때 개념적으로

은 (는 temp 실제로 this 것을 중요하지) 때문에 액세스가 거부되었습니다. protected 회원에게 액세스하는 "파생 된 클래스 권한"은 this에서만 작동합니다.

1

클래스의 복사본이 아니며 기본 클래스 개체에 대한 참조이므로 다른 클래스와 마찬가지로 다형성으로 동작합니다.

보호 된 구성원에 액세스 할 수없는 이유는 개인 상속을 사용했기 때문입니다.

+0

설명 할 수 있습니까 ** 보호 된 멤버에 액세스 할 수없는 이유는 개인 상속 **을 사용했기 때문입니다. 파생 클래스는 클래스의 범위 내에서 상속이 private인지 또는 public인지 여부에 따라 보호 된 멤버에 액세스 할 수 있으므로 감사 –

관련 문제