본문 바로가기

Language/C++

함수 오버라이딩

함수 오버라이딩

함수 오버라이딩은 많은 사람들이 재정의 로 알고 있는데 함수 오버라이딩 = 재정의 라는 이론은
잘못된 생각이다. 그 이유를 함께 알아보자!...ㅋㅋㅋㅋㅋ

AAA클래스가 있고 BBB클래스가  AAA클래스를 상속 받았다고 가정하자. AAA클래스에 a() 라는 함수가
있는데 이를 BBB클래스에 a() 함수를 다시 만들게 되면 'AAA클래스의 a()함수는 BBB클래스에 의해서
오버라이딩 되었다' 라고 표현한다. 그리고 이때 Base class 의 AAA에 있는 a() 함수는 BBB클래스에 의해서
'은닉 되었다' 라고 표현한다.

이를 소스로 본다면.....
class AAA
{
public:
    void a()
    {
        cout<<"AAA"<<endl;
    }
};

class BBB:public AAA
{
public:
    void a()
    {
        cout<<"BBB"<<endl;
    }
};

int main(void)
{
    BBB b;
    b.a();//AAA 클래스의 멤버 함수는 BBB클래스 멤버함수에 의해 은닉되어져 BBB의 멤버 함수가 호출이 된다.

    return 0;
}

바로 이 부분이 오버라이딩의 시작이라고 볼수있다. AAA 클래스의 a() 가 호출이 되는것이 아니라 BBB클래스의 a()가 호출이
된다..(사실....BBB의 객체니까 당연한걸.ㅡㅡ 젠장..)

하지만 '은닉' 이라는 개념은 실상에서도 '가리다, 감추다' 와 같은 의미가 아닌가. 즉, 다른 시점에서 본다면 볼수도 있다는 것이다.
이때 다른 '시점' 이라는것이 바로 객체 포인트 라고 볼수있다. 객체 포인터의 특성은 Base class 는 상속 받은 Derived class 의 포인터를
모두 받을수 있다. 하지만 접근영역은 Base class 쪽으로 갈수록 영역이 좁아진다. 이 특성을 이용하여 main함수를 변경하면....
nt main(void)
{
    BBB* b = new BBB;
    b..a();

    AAA* a = b;
    a->a();//b클래스를 가리키고 있지만 AAA클래스의 포인터 변수이기 때문에 객체 포인터 특성상 AAA클래스의 객체는
            //BBB 객체를 가리키고 있어도 AAA클래스의 멤버함수만 호출이 가능하다.!
    delete b;

    return 0;
}

AAA클래스의 a() 함수를 호출할수가 있다. 여기까지 우선적으로 오버라이딩을 정리하면서 재정의 부분은 한번도 나오지 않았다. 여기서는 은닉! 이 중요~

재정의를 논하려면 virtual 키워드가 출연해야한다!