Computer Science/C & C++

[C++] Binding | 결합

lww7438 2020. 3. 6. 16:09

Binding

결합

- 컴파일러가 함수 호출 구문을 보고, 어떤 함수로 매칭시킬지 해석하는 과정을 "함수 이름을 Binding(결합)한다." 라 표현한다.
- C언어에서는 하나의 이름에 하나의 함수만 매칭되기 때문에, 바인딩 과정이 비교적 간단하다.
- C++에서는 함수 오버로딩 기능이나 가상 함수로 인해 하나의 이름에 여러 함수가 매칭될 수 있어, 바인딩 과정이 간단하지 않다.(함수 이름뿐만 아니라, 함수의 Signature(매개변수 정보)까지 조사해야 한다.)


Static Binding (Early Binding(초기 결합); 정적 바인딩)

- 컴파일 시간 동안에 일어나는 바인딩이다. (C++ Default)
- 실행 시간 동안에 일어나는 사용자의 입력 값에 관계없이, 매칭할 함수가 자명히 존재하는 경우에는 정적 바인딩이 수행된다.
- 가상 멤버 함수가 아닌 함수들에 대해서는 정적 바인딩이 수행된다.


Dynamic Binding (Lately Binding(말기 결합); 동적 바인딩)

- 가상 멤버 함수들 중 어떤 함수에 매칭되어야 하는지는 실행 시간동안 사용자의 입력에 따라 달라지는 경우가 있는데, 이러한 경우는 정적 바인딩이 불가능한 대표적인 사례이다.
- 위와 같이 컴파일 시간에 미리 바인딩이 불가능한 경우를 대비하여, 프로그램 실행시간 동안 가상 멤버 함수를 바인딩 하는 것이 동적 바인딩이다.
- 클래스 객체 포인터/참조가 가상 함수를 호출했을 때, 포인터/참조의 데이터형이 아닌, 지목하는 객체의 데이터형에 매칭되는 가상 함수를 실행시키는 것 또한 동적 바인딩의 대표적 사례이다.
- 기초 클래스 객체와 파생 클래스 객체간의 Upcasting*이 수행되기 위해서는, 동적 바인딩이 꼭 뒷받침되어야 한다.

* Upcasting (업 캐스팅)

- 기초 클래스 객체형 포인터/참조는 파생 클래스 객체를 지시/참조할 수 있게하는 기능이다. (IS-A 관계를 구현)
- 이 개념을 확장하면, 기초 클래스 객체를 지시하는 포인터 배열을 정의하면, 기초 클래스 객체와 파생 클래스 객체 두 가지 타입의 데이터를 저장할 수 있는 배열을 만드는 것이 가능한 것을 알 수 있다.
- \(\texttt{public}\) 상속에서는, 명시적인 데이터형 변환 없이도 언제든지 업 캐스팅이 가능하다. 또한, 함수의 매개변수 전달 과정에서도 업 캐스팅이 일어날 수 있다.
(하지만, 함수가 Call by Value 타입으로 매개변수를 전달한다면, 업 캐스팅은 일어나지 않는다.)
- 업 캐스팅은 Transitive한 성질을 갖고 있다. \(\texttt{Grandpa}\) 기초 클래스에서 파생된 \(\texttt{Father}\) 파생 클래스, \(\texttt{Father}\) 클래스에서 파생된 \(\texttt{Son}\) 파생 클래스가 있다면, \(\texttt{Grandpa}\) 클래스 객체의 포인터/참조는 \(\texttt{Grandpa}\), \(\texttt{Father}\), \(\texttt{Son}\) 객체 모두를 지시/참조 할 수 있다.

※ 업 캐스팅과 반대 개념인, Downcasting(다운 캐스팅)은 기초 클래스의 포인터/참조를 파생 클래스의 포인터/참조로 변환하는 것을 의미한다.
- 다운 캐스팅은 암시적 변환을 불허하며, 반드시 명시적 데이터형 변환 과정이 있어야 한다. (IS-A 관계의 비대칭성)