본문 바로가기

Today I Learned

23.02.16 - 정적 바인딩과 동적 바인딩, 가상 함수

정적 바인딩과 동적 바인딩은 OOP에서 사용하는 메소드 호출 방식이다.

 

정적 바인딩

컴파일 시간에 메서드 호출 대상 객체의 타입이 결정된다.

변수의 값에 따라 호출 대상이 달라지지 않고 빠르고 효율적이다.

 

동적 바인딩

실행 시간에 메서드 호출 대상 객체의 타입이 결정된다. 

메서드 호출 시점에 변수에 할당된 객체의 실제 타입을 검사해 호출대상을 결정한다.

실행시간에 호출 대상이 변경될 수 있으므로 느리고 비효율적이다.

 

 

 

가상 함수

가상함수는 부모 클래스에서 정의되고 자식 클래스에서 재정의 될 수 있는 멤버 함수이다.

부모 클래스에서 virtual 키워드를 통해 정의 할 수 있으며 자식 클래스에서 재정의할 때 virtual 키워드는 선택이다.

이렇게 자식 클래스가 부모 클래스의 가상 함수를 재정의 하는 것을 오버라이딩이라고 한다.

class Animal {
public:
    virtual void makeSound() {
        cout << "The animal makes a sound" << endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() {
        cout << "The dog barks" << endl;
    }
};

int main() {
    Animal* animal1 = new Animal();
    Animal* animal2 = new Dog();

    animal1->makeSound();  // output: The animal makes a sound
    animal2->makeSound();  // output: The dog barks
}

Animal 클래스에서 가상 함수 makeSound를 정의하고 Dog 클래스에서 그것을 오버라이딩했다.

animal1은 Animal을 가리키기 때문에 Animal::makeSound를 실행하지만 animal2는 Dog를 가리키기 때문에

Dog::makeSound를 실행한다. animal2의 포인터타입은 Animal이지만 런타임 시에 Dog 객체로 초기화됐기 때문이다.

이렇게 런타임 시 호출 대상이 변하는 것이 동적바인딩이다. 또한 똑같은 형식의 함수 makeSound가 가리키는 대상에 

따라 실행문이 달라지므로 다형성을 보여주는 예시이기도 하다.

 

가상 함수 테이블

객체는 클래스에 가상함수가 추가되면 가상함수 테이블을 만들고 그 테이블을 가리키는 포인터를 추가한다.

그래서 클래스에 가상함수가 추가되면 포인터 크기만큼 클래스 크기가 증가한다. 

자식 클래스에서 오버라이딩한 함수들은 자식 클래스의 가상 함수 테이블에 따로 추가되고 (부모클래스와 자식 클래스의 가상함수 테이블은 독립적이다) 오버라이딩하지 않고 상속받은 함수들은 부모 클래스의 가상함수 테이블로 찾아간다.

 

https://cppking.tistory.com/45

 

[C++] 가상 함수, 가상 파괴자

void main() { Human H("김사람"); Student S("이학생",1234567); Human *pH; Student *pS; pH=&H; // 당연히 가능 pS=&S; // 당연히 가능 pH=&S; // 가능 // pS=&H; // 에러 pS=(Student *)&H; pS->Intro(); } 자식은 부모 객체의 모든 것을

cppking.tistory.com