[OOP] 정적 바인딩, 동적 바인딩

세동네·2022년 6월 17일
1
post-thumbnail

프로그램을 위한 변수, 함수들은 그 내용을 저장할 메모리를 할당해야 한다. 그 이전에 변수 및 함수의 타입과 값이 결정되어야 하는데, 이 타입과 값을 결정하는 것을 바인딩(Binding)이라 한다.

바인딩을 언제 해주는지에 따라 정적 바인딩과 동적 바인딩으로 나뉘고, 변수의 바인딩과 함수의 바인딩도 조금 차이가 있다.

· 정적 바인딩

정적 바인딩(Static binding)은 변수 및 함수가 컴파일 타임에 바인딩되는 것을 말한다. 컴파일 타임은 단어 그대로 컴파일이 이루어지는 시점이며, 컴파일에 대한 설명은 이 포스팅에 간단하게 정리해 놓았다.

- 변수의 정적 바인딩

  • 변수가 선언될 때 정적 바인딩이 이루어진다. 즉,

    // Test.cpp
    int a = 5;
    
    int* pa;

    와 같이 변수를 선언하고 초기화해주는 그 자체가 정적 바인딩이다. 특정 값으로 초기화해주지 않아도 정적 바인딩이다. 변수 정적 바인딩의 핵심은 변수의 타입을 지정해주는 것이다. 정적 바인딩 단계에서 메모리에 어느 정도 크기를 올릴 것인지 결정된다.

- 함수의 정적 바인딩

  • 호출되는 함수가 점프할 주소를 컴파일 타임에 결정하는 것이 함수의 정적 바인딩이다. 일반적인 함수는 모두 정적 바인딩된다고 보면 된다.

· 동적 바인딩

동적 바인딩(Dynamic binding)은 런타임(Runtime)에 바인딩하는 것을 말한다. 프로그램의 실행 파일이 만들어지고 이를 실행하면서 변수 및 함수가 호출될 때 바인딩된다.

- 변수의 동적 바인딩

  • 이미 선언된 변수의 값을 변경할 때 변수가 동적으로 바인딩된다고 한다. 예시는 아래와 같다.

    // Test.cpp
    a = 10;
    
    pa = &a;

- 함수의 동적 바인딩

  • 이번 포스팅의 핵심이다. 함수의 동적 바인딩은 상속 관계에 있는 객체의 메서드에서 관찰할 수 있다. 특정 클래스 객체 포인터가 있을 때, 해당 포인터가 가리키고 있는 객체의 함수를 호출할 때 동적 바인딩이 이루어진다. 말로 설명하면 조금 어렵게 느껴질 수 있는데, 아래와 같은 예시 코드를 보자.

    // Test.cpp
    class Base {
    public:
    	Base() {}
    
    	void func() {
    		std::cout << "Base" << std::endl;
        }
    };
    
    class Derived : public Base {
    public:
    	Derived() {}
      
    	void func() {
    		std::cout << "Derived" << std::endl;
    	}
    };
    
    int main() {
    	Base base;
    	Derived derived;
    
    	Base* pBase = &base;
    
    	pBase->func();
    }
    =============== 출력 ===============
     Base

    Base 객체 포인터를 만들어 Base 객체를 가리키게 하였다. 아무런 문제 없는 코드로, "Base"라는 문자열이 정상적으로 출력된다. 이러한 단순 함수 호출을 바인딩이라 칭하는 이유는 포인터에 있다. 객체지향 언어에서 다형성에 의해 상속 관계에 있는 클래스끼리는 기초 클래스 객체의 포인터가 파생 클래스 객체를 가리킬 수 있다. 즉, 다음과 같은 코드가 가능하다.

    // Test.cpp
    int main() {
    	Base base;
    	Derived derived;
    
    	Base* pBase = &derived; // Base의 객체 포인터가 Derived 객체를 가리킴.
    
    	pBase->func();
    }

    상속의 정의에 따라 파생 클래스는 기초 클래스의 기능을 모두 포함하기 때문에 이러한 관계 설정이 가능하다. 그리고 이런 관계 설정을 '업 캐스팅(Up Casting)'이라 한다. 업 캐스팅이라는 용어는 상위 클래스로의 형변환을 의미한다.

    이때 pBase->func()의 결과는 "Derived"를 출력할 것으로 기대된다. 실제 출력 결과는 다음과 같다.

    =============== 출력 ===============
     Base

    이는 선언된 객체의 타입이 우선되기 때문인데, 만약 호출할 메서드가 가상 함수라면 현재 객체 포인터가 가리키는 객체가 무엇인지에 따라 재정의된 메서드로 동적 바인딩이 이루어지는 것이다.

0개의 댓글