파생 클래스에 기본 클래스 포인터를 할당하는 중에 문제가 발생했습니다.
曾经蜡笔没有小新
曾经蜡笔没有小新 2017-06-05 11:11:46
0
3
1211

파생 클래스 주소를 기본 클래스 포인터에 할당합니다. 즉, 기본 클래스 포인터는 파생 클래스 객체를 참조하며, 이를 일반적으로 다형성이라고 부릅니다.

그러나 반전된 경우에는 컴파일하기 전에 강제로 컴파일해야 합니다.

직접 코드 다운로드:

으아악

pd->print()를 사용할 때 기본 클래스의 print가 호출되는 이유가 무엇인지 묻고 싶습니다

그럼 기본 클래스의 가상을 제거한 후 파생 클래스의 인쇄를 호출하는 이유는 무엇입니까

曾经蜡笔没有小新
曾经蜡笔没有小新

모든 응답(3)
滿天的星座

어떤 가상 함수를 호출할지는 객체가 가리키는 가상 함수 테이블에 따라 결정됩니다. new Base()를 사용할 때 pb가 가리키는 가상 함수 테이블의 가상 함수는 (Derived*)를 사용하여 강제 변환됩니다. 변경하지 않음 변경 사항, 비가상 함수는 주로 포인터 유형을 기반으로 합니다. 즉, pd는 처음부터 파생되므로 파생 함수를 사용하면 멤버 함수는 호출 시 실제로 이 포인터를 호출합니다.

刘奇

가상 지정자는 비정적 멤버 함수가 가상임을 지정하고 동적 바인딩을 지원합니다. 이는 비정적 멤버 함수의 초기 선언의 decl-specifier-seq에만 나타날 수 있습니다(즉, 클래스 정의).

가상 함수는 파생 클래스에서 동작을 재정의할 수 있는 멤버 함수입니다.

virtual을 사용한다는 것은 이 함수가 서브클래스에 의해 재정의될 수 있다는 것을 의미하므로, 서브클래스를 가리키는 부모 클래스 포인터는 포인터 자체의 카테고리에 따라 이 함수를 호출하지 않으며, (가상 함수 테이블 V-Table을 확인하여) 하위 클래스에 의해 재정의된 후의 함수를 함수라고 합니다.
언급할 가치가 있습니다

으아아아

이렇게 쓰는 것은 올바르지 않거나 적어도 안전하지 않습니다. 상위 클래스 객체를 가리키는 상위 클래스 포인터를 하위 클래스 포인터에 할당하면 안 됩니다.

여기서 pd->print는 가상 함수 테이블의 상위 클래스 인쇄를 가리킵니다. 따라서

으아아아

통화는 Base::print

입니다.

다음

으아아아

부모 클래스 객체에서 서브클래스의 함수를 강제로 호출하는 것입니다. (또는 부모 클래스 객체를 그대로 사용하고 가상 함수 테이블에서 서브클래스 인쇄를 강제로 호출하는 방법입니다.) 이는 일반적으로 권장되지 않습니다.

伊谢尔伦

정말 그런 경우인데 그냥 실행해 보니 정말 이해하기 어렵네요.

제 생각이 맞는지 아닌지 이야기해 보겠습니다. 참고하시면 됩니다.

첫 번째 경우에는 virtual이 작성됩니다. virtual을 추가하면 호출된 함수의 주소가 실행 중에만 발견된다는 의미입니다. 하지만 어디서 찾을 수 있나요? 각 개체의 메모리에 가상 테이블이 있는 것 같습니다(각 클래스에는 개체가 공유하는 가상 테이블이 있다고도 함). Derived 포인터가 Base 개체의 메모리를 가리키기 때문에 시스템은 다음과 같이 진행됩니다. 메모리의 가상 테이블에서 인쇄 함수를 찾으세요. 메모리의 가상 테이블에 있는 인쇄 함수의 주소는 Base 클래스의 인쇄 함수 주소이므로 기본 클래스의 인쇄 함수는 다음과 같습니다. 불렀어

두 번째 경우: 가상을 사용하는 경우 동적 바인딩이 포함되지 않습니다. 함수의 주소는 컴파일 중에 결정됩니다. 컴파일 중 함수 주소를 결정하는 방법: 소스 프로그램 기호 테이블을 검색하여 얻습니다. 그런 다음 주 프로그램의 pd->print()는 분명히 pd가 Derived 클래스이고 pd->print()가 Derived::print와 동일하므로 컴파일러는 이를 Derived 클래스에서 찾습니다. pd는 컴파일 중에 사용됩니다. ->print()의 print() 주소가 Derived::print의 주소로 대체되므로 하위 클래스의 인쇄 함수가 호출됩니다.

내 말을 이해하셨는지 모르겠네요

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿