12.3 override, final, 공변(Covarient) 반환형
#include <iostream>
using namespace std;
class A
{
public:
virtual void print(int x) { cout << "A" << "\n"; }
};
class B : public A
{
public:
void print(short x) override { cout << "B" << "\n"; } // 이 함수는 무조건 override라고 적어주는 것. 오류가 뜨면 수정할 수 있다.
// override 대신 final을 넣어주면 class C부터는 오버라이드가 불가능.
};
class C : public B
{
public:
void print() { cout << "C" << "\n"; }
};
class D : public C
{
public:
void print() { cout << "D" << "\n"; }
};
int main()
{
A a;
B b;
A &ref = b;
ref.print(1); // 이렇게 virtual이 있어도 파라미터가 다르면 오버로딩을 하지 않는다. 그럼 override를 추가하면 된다.
return 0;
}
공변 반환형
#include <iostream>
using namespace std;
class A
{
public:
virtual void print() { cout << "A" << "\n"; }
virtual A* getThis() { return this; }
};
class B : public A
{
public:
void print() override { cout << "B" << "\n"; }
virtual B* getThis() { return this; } // 일반적으로 return type이 다르면 오버라이드가 안되지만 부모-자식 클래스기 때문에 가능하다.
};
class C : public B
{
public:
void print() { cout << "C" << "\n"; }
};
class D : public C
{
public:
void print() { cout << "D" << "\n"; }
};
int main()
{
A a;
B b;
A &ref = b;
b.getThis()->print(); // B
ref.getThis()->print(); // A // ref의 타입이 A이기 때문에 B의 getThis에서 B의 포인터를 return 해주어도 타입을 A로 내부적으로 바꾸어 호출해 주는 구조이다.
// B의 getThis -> class A 반환 -> A의 print 호출
cout << typeid(b.getThis()).name() << "\n"; // class B *
cout << typeid(ref.getThis()).name() << "\n"; // class A *
return 0;
}