class A{
public:
virtual void doWork() { printf(" I am A");}
};
class B : public A
{
public:
virtual void doWork(); { printf(" I am B");}
};
using namespace std;
unique_ptr<A> object = make_unique<B>();
object->doWork();
하면 어떻게 될까?
B클래스에서 doWork()를 재정의 하였기 때문에
당연히 "I am B" 가 출력이 된다.
이와 같이 멤버함수의 재정의를 하기 위해선 몇 가지 조건을 만족해야 한다.
* 기본 클래스 함수가 반드시 가상 함수이어야 한다.
* 기본 함수와 파생 함수의 이름이 반드시 동일해야 한다 (소멸자는 예외)
* 기본 함수와 파생 함수의 파라미터 형식들이 동일해야 한다.
* 기본 함수와 파생 함수의 const 성이 동일해야 한다.
* 기본 함수와 파생 함수의 반환 형식과 예외 명세가 반드시 호환되어야 한다.
여기까지는 C++98 에도 있던 것이다.
그리고 C++11 에는 다음과 같은 조건이 하나 더 추가된다.
멤버 함수들의 참조 한정사(reference qualifier)들이 동일해야 한다.
그렇다면 참조 한정사가 뭘까?
멤버 함수를 왼값 또는 오른쪽값에만 사용할 수 있게 제한할 수 있는 기능이다.
이렇게 설명하면 뭔말인지 잘 모를테니
예제를..
class Widget {
public:
void doWork() &; // *this가 왼값일때만 적용
void doWork() &&; // *this가 오른값일때만 적용
};
Widget makeWidget(); // 인스턴스를 생성 및 반환하는 함수를 만들었다고 가정
Widget w; // w 라는 왼쪽값 생성
그리고 다음과 같이 호출해보자.
makeWidget().doWork(); // void doWork() & 호출
w.doWork(); // void doWork() && 호출
=> 왼쪽,오른쪽값에 따라 다른 멤버함수가 호출되는 것을 볼 수 있다.
다음은 override 에 대한 설명이다.
class A{
public:
virtual void mf1() const;
virtual void mf2(int x);
virtual void mf3() &;
void mf4 const;
};
class B{
public:
virtual void mf1();
virtual void mf2(unsigned int x);
virtual void mf3() &&;
void mf4 const;
};
B클래스는 A클래스를 상속받아 다음과 같은 함수들을 선언하였는데..
컴파일은 될까?
당연히 된다.
하지만, 여기서 프로그래머가 함수들을 재정의하려고 의도하였는지는 모르겠으나,
재정의가 되진 않았다.
아시다시피 앞서 설명한 재정의 규칙에 맞지 않기 때문이다.
class B{
public:
virtual void mf1() override;
virtual void mf2(unsigned int x) override;
virtual void mf3() && override;
void mf4 const override;
};
그렇다면 이렇게 override 라는 키워드를 붙여주면 어떨까?
컴파일러가 에러를 뿜어준다.
이것이 override 를 사용하는 이유이다.
멤버함수를 재정의하겠다는 프로그래머의 의도를 컴파일러가 지적해 주는 역할을 한다.
결론이다.
Base 클래스의 가상 함수를 재정의하려는 의도를 가진 멤버함수를
파생 클래스 안에서 선언할 때에는 그 함수를 반드시 override 로 선언하라
'프로그래밍 > C++' 카테고리의 다른 글
printf 류 함수에서 int64 형 데이터 사용방법 (0) | 2016.09.22 |
---|---|
C++11 스마트포인터 (0) | 2016.07.20 |
C++11 이동생성자 (Move Constructor) (2) | 2016.07.05 |
C++ 포인터와 참조의 차이 (0) | 2016.07.04 |
C++11 RValue Reference - 우측값 참조 (0) | 2016.07.04 |