일반적으로 부모클래스에 정의된 멤버 함수를 자식 클래스에서 재정의하는 것을 오버라이딩(overriding)이라고 하는데, 이 오버라이딩은 함수 이름, 매개 변수, 반환 타입까지 같아야 한다고 알고 있을 것이다. 하지만 아래 경우처럼 부모 클래스에서 정의한 함수를 자식 클래스에서 오버라이딩할 때, 그 오버라이딩 하려는 함수의 타입을 자식 클래스 타입으로 하면 오버라이딩 함수의 타입을 다르게 해도 오버라이딩이 가능하다(근본적으로는 타입이 다르다라고 할 순 없다. 이 경우 covariant한 타입이라고 표현을 하더라)
class CParent
{
public:
CParent();
virtual ~CParent();
CParent(const CParent& Parent);
virtual CParent* Clone()
{
std::cout << "Parent Clone" << std::endl;
return new CParent(*this);
}
};
class CChild :
public CParent
{
public:
CChild();
virtual ~CChild();
CChild(const CChild& Child);
virtual CChild* Clone()
{
std::cout << "Child Clone" << std::endl;
return new CChild(*this);
}
};
int main()
{
std::list<CParent*> m_List;
CChild* NewChild = new CChild;
m_List.push_back(NewChild);
auto iter = m_List.begin();
(*iter)->Clone();
delete (*iter);
return 0;
}
정상적으로 NewChild의 정적 타입은 CParent*일지 몰라도 CChild를 생성했으므로, 동적 바인딩이 CChild의 Clone으로 되어서 CChild::Clone이 불렸음을 확인할 수 있다. 이런 예외적인(?) 사실을 stackoverflow에서도 찾아볼 수 있었다.
결론적으로 CChild와 CParent는 covariant한 타입이므로 오버라이딩시 타입을 각자 타입으로 다르게 해도 문제가 되지 않는다는 것이다.
Reference
https://stackoverflow.com/questions/4665117/c-virtual-function-return-type
'공부 > C || C++' 카테고리의 다른 글
C++ 변환 연산자(Conversion Operator) (0) | 2021.08.28 |
---|---|
C++ vector의 resize vs reserve (0) | 2021.08.25 |
C++ 자식 클래스 복사 생성자 초기화 리스트에서 부모의 복사 생성자 호출하는 방법 (0) | 2021.08.17 |
C++ return new(*this); 는 복사 생성자를 호출한다 (0) | 2021.08.17 |
C/C++ 파일 입출력 (0) | 2021.08.14 |