c++ 가상함수 예제

클론() 멤버 함수에서 새 Circle(*this) 코드는 Circle의 복사 생성기를 호출하여 새로 생성된 Circle 개체에 이 상태를 복사합니다. (참고: Circle이 최종(일명 리프)인 것으로 알려져 있는 경우가 아니면 복사 생성기를 보호하여 슬라이스 가능성을 줄일 수 있습니다. create() 멤버 함수에서 새 Circle() 코드는 Circle의 기본 생성자입니다. 가상 함수는 기본 클래스 내에서 선언되고 파생 된 클래스에 의해 다시 정의 (재정의)되는 멤버 함수입니다. 포인터 또는 기본 클래스에 대한 참조를 사용하여 파생 된 클래스 개체를 참조할 때 해당 개체에 대한 가상 함수를 호출하고 파생 된 클래스의 함수 버전을 실행할 수 있습니다. 참고: 기본 클래스에서 가상 함수를 만들고 파생 클래스에서 재정의된 경우 파생 클래스에 가상 키워드가 필요하지 않으며 함수는 파생 클래스의 가상 함수로 자동으로 간주됩니다. 참고: Circle의 복제() 멤버 함수의 반환 형식은 Shape의 복제() 멤버 함수의 반환 형식과 의도적으로 다릅니다. 이를 원래 언어의 일부가 아닌 기능인 Covariant 반환 유형이라고 합니다. 컴파일러가 클래스 서클 내의 Circle* clone() const의 선언에 불만을 제기하는 경우(예: “반환 형식이 다릅니다” 또는 “멤버 함수의 형식이 반환 형식에 의해 기본 클래스 가상 함수와 다릅니다”) 이전 컴파일러가 있고 반환 유형을 Shape*로 변경해야 합니다. 이제 위의 질문에서 해결되는 경우: 정규화된 이름(클래스 이름 뒤에 “::”)을 사용하여 가상 함수를 호출할 때 컴파일러는 가상 호출 메커니즘을 사용하지 않고 대신 비 가상 함수. 다른 방법으로, 그것은 슬롯 번호보다는 이름으로 함수를 호출합니다.

따라서 파생 클래스 Der 내의 코드를 Base::f() 호출하려는 경우, 즉 기본 클래스 Base에 정의된 f() 버전인 경우 파생 클래스를 작성해 보겠습니다. C++ 코드가 클래스 Base에서 상속되는 클래스 Der를 정의한다고 가정합니다. 컴파일러는 #1 단계를 반복하고 #3(#2 아님). #1 단계에서 컴파일러는 Base:::_vtable과 동일한 함수 포인터를 유지하면서 재지정에 해당하는 슬롯을 대체하는 숨겨진 v-table을 만듭니다. 예를 들어, Der가 virt2()를 통해 virt0()를 재정의하고 다른 테이블을 있는 것처럼 상속하는 경우 Der의 v-table은 다음과 같이 보일 수 있습니다(Der가 새 가상을 추가하지 않는 척) 이제 기본 클래스에서 가상 함수를 사용했기 때문에 원하는 출력을 얻을 수 있습니다. 파생 클래스의 멤버 함수를 사용하여 재정의합니다.