[C++] C++11 override, final
글 작성자: Sowhat_93
C++11 에 override 와 final 키워드가 추가되었다.
아래의 코드를 보도록 하자.
1. override
#include <iostream> class EntityBase { public: virtual void Print() { std::cout << " I am Base !" << std::endl; } EntityBase () { } virtual ~EntityBase () { } }; class EntityTypeA : public EntityBase { public: void Print() { std::cout << "I am Type A Entity !" << std::endl; } EntityTypeA() { } virtual ~EntityTypeA() { } }; class EntityTypeB : public EntityTypeA { public: void Print() { std::cout << "I am Type B Entity !" << std::endl; } EntityTypeB() { } virtual ~EntityTypeB() { } }; int main() { EntityBase* p = new EntityTypeB(); p->Print(); }
결과는 "I am Type B Entity" 가 출력된다.
최상위 클래스인 EntityBase 의 함수가 virtual 로 정의 되어 있고,
하위 클래스들이 최상위 클래스의 시그니쳐에 따라 얌전히 재정의 하고있다.
그런데, 만약 다음과 같은 경우라면?
class EntityTypeA : public EntityBase { public: void Print(int A) { std::cout << "I am Type A Entity !" << std::endl; } EntityTypeA() { } virtual ~EntityTypeA() { } }; class EntityTypeB : public EntityTypeA { public: void Print(int A) { std::cout << "I am Type B Entity !" << std::endl; } EntityTypeB() { } virtual ~EntityTypeB() { } };
결과는 " I am Base !" 가 출력된다.
EntityBase* p = new EntityTypeB(); p->Print();
가지고 있는 포인터는 EntityBase 형 포인터이다 때문이다.
가상함수 호출시 실제 객체의 vfptr을 참조하게 되는데,
이때의 Print, 즉 시그니쳐가 void 반환형에 void 인자인 경우를 찾게된다.
없으니 EntityBase의 함수가 호출된다.
이름이 같을 뿐 결국 다른 함수 취급이 되는거다.
여기서 override keyword를 사용해보자.
class EntityTypeA : public EntityBase { public: void Print(int A) override { std::cout << "I am Type A Entity !" << std::endl; } //컴파일 에러. //override-> 내가 상위클래스의 void Print(int) 를 재상속 한것임을 선언. //?? 없는데? void Print(void) 인데?? EntityTypeA() { } virtual ~EntityTypeA() { } }; class EntityTypeB : public EntityTypeA { public: void Print() override { std::cout << "I am Type B Entity !" << std::endl; } //무리없이 okay EntityTypeB() { } virtual ~EntityTypeB() { } };
컴파일 에러가 난다.
이름이 같을뿐 함수의 시그니쳐가 다르기 때문이다.
override keyword는 이 함수가 상위 클래스의 가상함수를 재정의 했음을 나타내는데,
컴파일러가 상위 클래스에서 아무리 찾아봐도 없기 때문에 컴파일 오류가 나는 것이다.
override를 붙이던 안붙이던
상위클래스의 가상함수와 하위클래스에서의 함수가 시그니쳐가 같다면 잘 호출 된다.
허나 협업시 명시적으로 override를 했음을 확실시하고 실수를 방지하기 위해 붙이도록 한다.
2. final
하위 클래스에서의 재정의를 막아버린다.
재정의시 컴파일 에러.
class EntityBase { public: virtual void Print() { std::cout << " I am Base !" << std::endl; } EntityBase () { } virtual ~EntityBase () { } }; class EntityTypeA : public EntityBase { public: void Print() final { std::cout << "I am Type A Entity !" << std::endl; } EntityTypeA() { } virtual ~EntityTypeA() { } }; class EntityTypeB : public EntityTypeA { public: void Print() override { std::cout << "I am Type A Entity !" << std::endl; } //컴파일 에러 ! void Print(int A) { } //이름만 같을 뿐 별개의 함수. //컴파일 Okay. EntityTypeB() { } virtual ~EntityTypeB() { } };
'C++' 카테고리의 다른 글
[C++] STL Custom Allocator 사용 (0) | 2022.04.08 |
---|---|
[C++] C++ 11 mutable (0) | 2022.03.28 |
[C++] new[] , delete[] 오버로딩시 주의 사항. (0) | 2022.03.28 |
[C++] const lvalue reference, rvalue reference (2) | 2022.03.23 |
[C++] C++11 constexpr (0) | 2022.03.20 |
댓글
이 글 공유하기
다른 글
-
[C++] STL Custom Allocator 사용
[C++] STL Custom Allocator 사용
2022.04.08 -
[C++] C++ 11 mutable
[C++] C++ 11 mutable
2022.03.28 -
[C++] new[] , delete[] 오버로딩시 주의 사항.
[C++] new[] , delete[] 오버로딩시 주의 사항.
2022.03.28 -
[C++] const lvalue reference, rvalue reference
[C++] const lvalue reference, rvalue reference
2022.03.23
댓글을 사용할 수 없습니다.