1] 오버라이딩의 이해
BBB 객체 |
void AAA::fct(){..} |
void BBB::fct({..} |
위 표와 같이 BBB 객체안에 AAA 클래스에 선언된 fct 와 BBB클래스에서 정의한 fct 함수가 잇다고 하자! 그리고 BBB클래스스의 fct함수는 AAA클래스를 가르키나다. 즉 AAA클래스가 base클래스이고 BBB 클래스가 Dervied클래스 이다./ BBB클래스의 fct함수가 AAA 클래스의 fct 함수를 가리킨다. 이처럼 Base클래스에 선언도니 형태의 함수를 Derived 클래스에서 다시 선언하는 현상을 가리켜 오버라이딩(overriding) 이라 한다. 이것을 실행하면 BBB클래스의 fct함수가 호출된다. 즉
오버라이딩은 이전에 정의된 함수를 가리는(hide) 특성을 지닌다고 할수 있다.
- 물론 포인터를 이용하여...호출하면 가려지는것 호출가능
ex) a->fct();
b->fct();
2] 멤버 함수를 가상(virtual)으로 선언하기
ex)
class AAA{
virtual voide fct()
}
오버라이딩되는 함수를 가상으로 선언할 수 있다. 가상으로 선언한다는 의미는 virtual 키워드를 이용해서 함수가 dynamic binding을 하게끔 한다는 의미이다.
가상현실 은 실제 존재하지 않는 싸이버 공간의 현실 세계를 표현하는 말이다. 이처럼 가상이라는 단어의 뜻에는 실제로 존재하지 않는 허상의 의미가 있다.
AAA클래스에 선언되어 있는 fct 함수를 가상함수 즉 존재하지 않는 함수로 선언하고 있다(존재하고 있지만;;) 그러므로 AAA 타입의 포인터로 접근을 한다고 해서 호출될 리 만무하다. 존재하지 않으니 말이다. 대신 BBB 클래스에 선언되어 있는 fct함수가 호출된다.
3] 가상함수의 특성은 상속된다.
가상함수는오버라이딩관계에서 상속될때만...의미를 지니게 된다.
class AAA{
public: virtual void fct(){}
};
class BBB: public AAA
{
public
void fct() { // virtual void fct(); AAA클래스를 상속하고 오버라이딩관계에 있다. 그러할 경우 자동 virtual // 된다.. 코드 가독성을 위해 써주는게 좋음..virtual 이라고...
};
class CCC:public BBB virtual 특성이 그대로 상속되어져서
{
void fct(){} //BBB클래스의 virtual 특성이 그대로 상속되어져서 virtual void fct() 가 된다.
}
_M#]_M#]
CCC클래스의 fct함수가 BBB클래스의 fct 함수를 다시 오버라이딩하고있다.
BBB클래스의 fct함수가 AAA클래스의 fct 함수를 다시 오버라이딩하고있다.
b->fct (); 를 하면 BBB클래스의 fct함수대신에 BBB클래스의 fct함수를 오버라이딩하고있는 CCC클래스의 fct함수를 대신호출한다.
a->fct (); 를 하면 AAA클래스의 fct함수대신에BBB클래스의 fct함수를 대신 호출 그리고 BBB클래스의 fct함수를 오버라이딩하고있는 CCC클래스의 fct함수를 다시 대신 호출한다.
컴파일할 때 어떤 객체가 만들어질지 모르는 상태에서 호출될 멤버 함수가 결정되는 정적 바인딩을 한다.. 호출될 함수가 실행할 때 결정되도록 하는것을 동적바인딩이라고합니다. 동적 바인딩을 가능하도록 하는것이 바로 가상함수이다.
A* a = new ??? A {}f()<-(상속) B {}f()<-(상속)C {}f()
a->f() 어디에 존재하는 f() 함수가 호출이될까 그것은 포인터에 의해서 호출함수 결정되는게 아니라 포인터가 가리키는 객체에 따라서 호출될 함수가 달라진다. 이것을 동적바인딩이라고 한다. dynamic binding 이라고한다. (상황에따라 달라지는 것)
A a;
a.f(); -> 이와 같은 경우는 A클래스의 f 라고 정해져 잇다 이런것을 static binding 이라고 한다.
오버라이딩된 함수 호출하기 - 오버라이딩된 함수는 가려진다고 했다 그렇다면 절대 호출 불가능한 것일까?
오버라이딩된 함수를 호출하려면 범위 지정 연산자(::)를 통해서 오버라이딩된 함수도 호출이 가능하다
ex)
class A{
public:
virtual void fct(){}
};
class B :public A
{
public:
void fct(){
A::fct() // 호출 방법!!
}
};
함수의 오버라이딩과 가상 함수는 재활용과는 다소 거리가 있다 오히려 확장성에 더 큰 의미가 있다.
'C++' 카테고리의 다른 글
cout / cin / endl 에 대하여... (0) | 2009.02.10 |
---|---|
단항 연산자의 오버로딩 (0) | 2009.02.09 |
연산자 오버로딩 (0) | 2009.02.06 |
클래스 멤버함수는 // virtual의 원리 // 다중상속 * 다시 봐야될듯.ㅠ (0) | 2009.02.05 |
순수(pure) 가상함수와 추상(abstract)클래스 (0) | 2009.02.04 |
상속된 객체와 참조의 관계 (0) | 2009.02.03 |
상속된 객체와 포인터의 관계 (0) | 2009.02.03 |
상속의 조건 (0) | 2009.01.19 |
클래스... (0) | 2009.01.16 |
상속을 하는 이유 (0) | 2009.01.16 |