본문 바로가기

Information Technology/C++

[C++] 정적 바인딩과 동적 바인딩

이 글은 개인의 학습을 목적으로 정리한 글입니다. 이점 참고하고 읽어주세요 ;)


이번 포스팅에서는 정적 바인딩동적 바인딩에 대해 다뤄보겠습니다.

 

우선 정적 바인딩과 동적 바인딩을 다루기 전에, 바인딩(Binding)이란 무엇일까요?

바인딩(Binding)이란 대략적으로 프로그램 구성 요소의 성격을 정해주는 것입니다. 예를 들어 변수를 하나 정의한다면, 그 변수의 데이터 타입이 무엇인지 결정해주는 걸 생각하면 될 것 같습니다.

 

함수 역시 바인딩을 필요로 합니다. 우리는 프로그램에서 함수를 만들어 컴파일을 하게 되면 각각의 함수를 정의하는 코드들이 메모리 어딘가에 저장이 됩니다. 그리고 함수를 호출할 때에는 main 함수 혹은 다른 함수에서 사용하려는 함수가 저장된 주소값으로 가서 함수를 실행하고, 다시 원래의 위치로 돌아오게 됩니다. 이 과정에서 함수를 호출할 때 함수가 위치한 메모리 주소값으로 연결시켜주는 걸 바인딩(Binding)이라고 합니다.

이 바인딩이 정적(static)으로 이뤄지느냐, 동적(dynamic)으로 이뤄지느냐에 따라 정적 바인딩과 동적 바인딩이 구분되는데요, 자세한 내용은 예제 코드를 통해 설명하겠습니다.


#include <iostream>
using namespace std;

int add(int x, int y)
{return x + y;}

int subtract(int x, int y)
{return x - y;}

int multiply(int x, int y)
{return x * y;}

우선 각각의 add, subtrack, 그리고 multiply 함수를 정의했습니다. 매개변수는 모두 int형 변수 두 개로 동일합니다.

 

int main()
{
	int x, y;
	cin >> x >> y;

	int op;
	int result;
	cout << "0: add, 1: subtract, 2: multiply" << endl;
	cin >> op;

	switch (op)	// 호출할 함수를 컴파일 단계에서 미리 결정
	{
	case 0: result = add(x, y); break;
	case 1: result = subtract(x, y); break;
	case 2: result = multiply(x, y); break;
	}

	return 0;
}

그리고 main 함수입니다. int형 변수 x와 y를 정의하고, 각각의 값은 사용자에게 입력받습니다.

우리는 switch 함수를 통해 입력받은 값에 따라 다른 함수를 호출시킬 건데요, 어떤 연산을 수행할지 결정하는 int형 변수 op를 정의하고 사용자에게 입력을 받습니다.

switch 문에서는 사용자에게 입력받은 op의 값에 따라 add, subtract, 그리고 multiply 함수가 호출되도록 정의되어 있습니다.

이렇게 컴파일 단계에서 호출할 함수를 미리 정하는 것을 정적 바인딩(static binding) 또는 Early binding이라고 합니다.

정적 바인딩은 이미 컴파일 단계에서 호출함 함수를 정하기 때문에 프로그램을 실행하고 함수를 호출할 때 동적 바인딩보다 빠른 속도를 보여줍니다.


int main()
{
	int x, y;
	cin >> x >> y;

	int op;
	int result;
	cout << "0: add, 1: subtract, 2: multiply" << endl;
	cin >> op;

	int (*func_ptr)(int, int) = nullptr; // 함수 포인터 func_ptr 정의
	switch (op)	// 함수 포인터가 찾아갈 함수의 주소가 런타임에서 결정
	{
	case 0: func_ptr = add; break;
	case 1: func_ptr = subtract; break;
	case 2: func_ptr = multiply; break;
	}

	cout << func_ptr(x, y) << endl;

	return 0;
}

이번에는 switch 문을 선언하기 전에, int형 함수 포인터 func_ptr을 정의하고 nullptr로 초기화했습니다.

그리고 switch 문에서는 사용자가 입력한 변수 op의 값에 따라 func_ptr이 각각 다른 함수를 찾아가도록 설정했습니다. 즉 func_ptr이 찾아갈 함수가 정적 바인딩처럼 컴파일 타임이 아닌, 런타임에서 결정되는 것입니다.

그리고 switch에서 자신이 찾아갈 함수를 찾은 함수 포인터 func_ptr을 호출하여 연산을 진행합니다.

이처럼 호출할 함수가 컴파일 타임이 아닌 런타임에서 결정되는 걸 동적 바인딩(dynamic binding) 또는 Late binding이라고 합니다.

동적 바인딩은 사용할 함수가 미리 정해져있지 않고 런타임에서 함수를 찾아가야 하기에 정적 바인딩에 비해 속도 측면에서는 느리지만, 대신 프로그램을 유연하게 설계할 수 있다는 장점이 있습니다.