나는 더 잘 읽을 수 있도록 대화 형식으로 답변을했습니다.
가상 기능이 필요한 이유는 무엇입니까?
다형성 때문에.
다형성이란 무엇입니까?
기본 포인터가 파생 된 형식 개체를 가리킬 수도 있습니다.
다형성에 대한 이러한 정의는 가상 함수의 필요성을 어떻게 이끌어 냅니까?
초기 바인딩을 통해 .
초기 바인딩이란 무엇입니까?
C ++에서 초기 바인딩 (컴파일 타임 바인딩)은 프로그램이 실행되기 전에 함수 호출이 수정되었음을 의미합니다.
그래서...?
따라서 기본 유형을 함수의 매개 변수로 사용하는 경우 컴파일러는 기본 인터페이스 만 인식하고 파생 클래스의 인수를 사용하여 해당 함수를 호출하면 잘려 나갑니다.
우리가 원하는 것이 아니라면 왜 이것이 허용됩니까?
다형성이 필요하기 때문에!
그렇다면 다형성의 이점은 무엇입니까?
기본 유형 포인터를 단일 함수의 매개 변수로 사용할 수 있으며, 프로그램 런타임에서 단일 유형의 역 참조를 사용하여 문제없이 각 파생 유형 인터페이스 (예 : 멤버 함수)에 액세스 할 수 있습니다. 기본 포인터.
나는 아직도 어떤 가상 기능이 좋은지 모른다! 그리고 이것은 나의 첫 번째 질문이었습니다!
글쎄, 당신이 너무 빨리 질문을했기 때문입니다!
가상 기능이 필요한 이유는 무엇입니까?
파생 클래스 중 하나에서 객체의 주소를 가진 기본 포인터로 함수를 호출했다고 가정하십시오. 위에서 언급했듯이 런타임 에서이 포인터는 역 참조되었지만 지금까지는 훌륭했지만 파생 클래스의 메서드 (= = 멤버 함수)가 실행될 것으로 기대합니다! 그러나 동일한 메소드 (같은 헤더를 가진 메소드)가 이미 기본 클래스에 정의되어 있으므로 프로그램에서 다른 메소드를 선택 해야하는 이유는 무엇입니까? 다시 말해, 이전에 일반적으로 발생했던 방식에서이 시나리오를 어떻게 알 수 있습니까?
간단한 대답은 "기본의 가상 멤버 함수"이고, 조금 더 긴 대답은 "이 단계에서 프로그램이 기본 클래스에서 가상 함수를 볼 경우 사용하려고한다는 것을 알고 있습니다 (실현) 다형성 "과 같은 방법으로 파생 클래스 ( v-table , 후기 바인딩 형식)를 사용하여 헤더가 동일하지만 구현 이 다른 다른 메소드 를 찾습니다 .
왜 다른 구현입니까?
너 너클 머리! 좋은 책을 읽으십시오 !
OK, wait wait wait, 왜 파생 형 포인터를 사용할 수있을 때 왜 기본 포인터를 사용하는 것이 좋을까요? 당신은 판사입니다.이 두통이 그만한 가치가 있습니까? 이 두 스 니펫을보십시오.
//1:
Parent* p1 = &boy;
p1 -> task();
Parent* p2 = &girl;
p2 -> task();
// 2 :
Boy* p1 = &boy;
p1 -> task();
Girl* p2 = &girl;
p2 -> task();
나는 생각하지만, OK, 1 보다 나은 여전히 2 , 당신은 쓸 수 1 과 같이 있습니다.
//1:
Parent* p1 = &boy;
p1 -> task();
p1 = &girl;
p1 -> task();
또한 지금까지 설명한 모든 내용이 아직 사용 중이라는 것을 알고 있어야합니다. 이 대신, 예를 들어 프로그램에서 각각의 파생 클래스 (getMonthBenefit ())의 메소드를 각각 사용하는 함수가있는 상황을 가정하십시오.
double totalMonthBenefit = 0;
std::vector<CentralShop*> mainShop = { &shop1, &shop2, &shop3, &shop4, &shop5, &shop6};
for(CentralShop* x : mainShop){
totalMonthBenefit += x -> getMonthBenefit();
}
이제 두통없이 다시 작성하십시오 !
double totalMonthBenefit=0;
Shop1* branch1 = &shop1;
Shop2* branch2 = &shop2;
Shop3* branch3 = &shop3;
Shop4* branch4 = &shop4;
Shop5* branch5 = &shop5;
Shop6* branch6 = &shop6;
totalMonthBenefit += branch1 -> getMonthBenefit();
totalMonthBenefit += branch2 -> getMonthBenefit();
totalMonthBenefit += branch3 -> getMonthBenefit();
totalMonthBenefit += branch4 -> getMonthBenefit();
totalMonthBenefit += branch5 -> getMonthBenefit();
totalMonthBenefit += branch6 -> getMonthBenefit();
그리고 실제로, 이것은 아직 고안된 예일 수도 있습니다!