title: “C++ 13. 가상 함수(오버라이딩과 동적바인딩)” categories:

  • CspecialCharspecialChar

    #C++ 13. 가상 함수(오버라이딩과 동적바인딩) : 네이버 블로그

일단 오버라딩에 대해 설명하겠다

​

오버라이딩은 한국어로 재정의이다.

​

즉 어떠한 변수나 함수를 재정의하는 것이다

​

​

오버라이딩을 하기 위해서는 virtual이 필요하다

이는 가상 함수로 불리는데 어떠한 함수나 변수의 정의를 늦춤으로써 다르게 정의된 함수나 변수가 있는지 확인 후 없으면 기존의 함수나 변수를 출력, 있으면 바뀐 함수나 변수를 출력한다.

​

즉 일단 미루고서 재정의된 함수나 변수가 있는지 찾고 있으면 바꾼다

​

간단히 예시를 들겠다

#include
using namespace std;
class people {
public:
 virtual void f() {
 cout << "people::f()" << endl;
 }
};
class student:public people {
public:
 void f() {
 cout << "student::f()"<<endl;
 }
};
int main() {
 student A;
 A.f();
}

people과 student는 각각 자신의 맴버 f를 가지고 있다

이 f는 이름과 매개변수가 같으므로 같은 함수이다(내용은 다름)

둘중 어떤것을 사용할지 구별하기 위해 people의 f는 virtual이 되어 있다

​

​

main안에서는 student A가 선언된다

A는 만들어지면서 student는 people을 상속함으로써 people의 맴버를 가져온다

people의 맴버는 f()지만 virtual이 있으므로 실행이 될때까지 기다린다

people이 만들어지고 student가 생성된다. student는 f를 가지고 있다

​

f는 student에 있으므로 people의 f가 아닌 student의 f가 사용된다

​

이렇게 클래스에 따라 각기 다른 맴버를 사용할 수 있다

​

​

우리는 이제 동적 바인딩에 대해서도 알아야 한다

동적 바인딩이란 가상 함수가 있는 코드를 컴파일 할 때 가상 함수를 필요할 때 찾아 쓰는 과정이다

​

즉 함수가 정의되어 사용되지 않고 호출된다면 오버라디이딩 된 함수 중에서 찾아 실행된다

​

먼저 에제를 보자

#include
using namespace std;
class people {
public:
 virtual void f() {
 cout << "people::f()" << endl;
 }
};
class student:public people {
public:
 void f() {
 cout << "student::f()"<f();

 people \*C=B;
 C->f();
}

main 안에만 보겠다

student A는 student 와 people의 맴버를 모두 갖고 있다

A.f()를 실행하게 되면 people에 있는 맴버는 virtual이므로 재정의되어 student에 있는 f가 실행되게 된다

​

이후 student *B는 A의 주소를 가진다

B의 f를 실행하게 되면 B는 student의 f를 실행하게 된다

​

3번째로 people *C가 선언된다

이 C는 B를 받음으로써 기본 클래스인 people부분만 받게 된다

C의 f()를 실행하게 되면 people객체 포인터므로 people의 f가 실행 된다 생각할 수도 있지만

student의 f가 실행되게 된다

​

왜 이런 결과가 나오게 되는 것일까

동적 바인딩이 발생하는 경우에는 파생 클래스의 객체에 대해, 기본 클래스의 포인터로 가상 함수가 호출될 때 일어난다.

​

​

​

즉 상속이 있고 기본클래스의 포인터로 가상함수가 호출될 때 동적 바인딩이 일어난다

이에 주의하면서 오버라이딩을 사용해야 한다.

​

​

​

우리는 오버라이딩을 사용하면서 맴버를 재정의 하는 방법을 알았다

그럼 재정의된 맴버를 사용할 수 없을까?

​

바로 범위지정연산자 :: 을 사용하면 된다

범위지정연산자를 사용하는 방법은 크게 두가지인데

클래스 외부에서 호출, 두번째는 클래스의 기능을 추가하는 것이다

위의 people, student를 가지고 계속 설명하자면

​

student A;
 people \*B = &A
 B->f();
 B->people::f();

student A를 선언하고

people *B=&A; //A의 주소를 B에 넣는다

B->f()를 하게 되면 재정의된 f,즉 파생 클래스인 student의 f가 실행된다

b->people::f()를 하게 되면 기본클래스의 맴버인 f()가 실행된다

​

이로써 오버라이딩과 동적 바인딩에 알아보았다

업데이트: