가상 함수의 기본값의 위험!
5835 단어 cpp
기사::기사
다음은 친구가 보낸 코드 스니펫입니다.
#include <iostream>
class Base
{
public:
virtual void rick(int x = 0)
{
if (0 == x)
std::cout << "Give you up\n";
else
std::cout << "Let you down\n";
}
};
class Derived : public Base
{
public:
virtual void rick(int x = 10)
{
if (0 == x)
std::cout << "Run around and desert you\n";
else
std::cout << "Make you cry\n";
}
};
int main()
{
Derived d1;
Base* bp = &d1;
std::cout << "Never gonna ";
bp->rick();
return 0;
}
Compiler explorer link
무엇을 인쇄할지 짐작할 수 있습니까? 바로 위의 컴파일러 탐색기 링크에서 솔루션을 볼 수 있습니다.
개인적으로 올바른 솔루션을 찾았지만 두 가지가 도움이 되었습니다. 첫째, 친구가 저를 속이려고 이 스니펫을 보낸다는 것을 알았습니다. 상속 및 기본값. 실제 프로젝트에서는 이것을 발견하는 것이 그렇게 간단하지 않을 수 있습니다.
이제 이것이 왜 이렇게 작동하는지 살펴보겠습니다!
설명
약간의 요약
Base
라는 기본 클래스와 Base
라는 이름의 Derived
에서 상속받은 클래스가 있습니다. (원래 얼마나)virtual void Base::rick(int x = 0)
에 가상 멤버 함수Base
가 있고 Derived
에 같은 이름을 가진 함수가 있습니다: virtual void Derived::rick(int = 10)
두 멤버 함수 모두 x
값에 따라 다른 텍스트를 인쇄합니다.기본 함수에는
Derived
멤버 함수를 호출하기 위해 Base*
를 통해 액세스하는 rick
개체가 있습니다.출력이 무엇인지 추측하려고 하면 네 가지 가능성이 있음을 의미합니다.
단계별 분석
rick
가 호출되고 rick
가 Base
에서 정의되고 Derived
에서 재정의되는 것을 추론하는 것으로 시작하겠습니다. 예, 기본값이 프로토타입의 일부가 아닙니다.이제 어느 것이 호출되는지 아는 것이 매우 쉽다는 것을 알고 있습니다.
x
객체가 있고 함수는 가상이며 포인터를 통해 호출하면 Derived
를 호출합니다.두 가지 가능성이 남아 있습니다.
기본 인수가 10인치
virtual void Derived::rick
이기 때문에 "Never gonna Make you cry"라고 대답하고 싶은 유혹을 느낄 수 있지만 이는 잘못된 것입니다. 실제 출력은 "Never gonna Run Around and Desert You"이고 여기서 유일한 버그는 의자와 키보드 :)왜 그렇게 합니까?
표준이 그렇게 말하고 있기 때문입니다.
The overriders of virtual functions do not acquire the default arguments from the base class declarations, and when the virtual function call is made, the default arguments are decided based on the static type of the object
이는 문자 그대로
virtual void Derived::rick(int x = 10)
유형의 객체가 있고 Derived
를 호출하는 경우 인수의 기본값이 호출되는 구현에 의존하지 않는다는 것을 의미합니다.기사::~기사
보시다시피 동작은 논리적이지만 직관적이지 않고 파악하기 어려울 수 있습니다. 그렇기 때문에 이것을 사용해서는 안 된다고 생각하지만, 당신이 그것을 사용할 만큼 미쳤다면 다른 개발자들에게 이것에 대해 경고할 수 있는 주석과 문서가 있어야 합니다.
출처
Reference
이 문제에 관하여(가상 함수의 기본값의 위험!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/baduit/the-dangers-of-default-value-with-virtual-functions-5ccm텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)