가상 함수

jaehun_dev·2022년 12월 1일
0

C++

목록 보기
3/3

가상 함수

파생 클래스에서 재정의할 것으로 기대하는 멤버 함수.

정적 바인딩

일반적으로 C++ 컴파일러는 함수 호출 시 어느 블록의 함수인지, 해당 함수의 메모리 상 위치 등의 정보를 요구한다. 함수 호출 코드로부터 이러한 정보를 해석하는 것을 바인딩(binding)이라 한다. 대부분의 함수 호출은 컴파일 타임에 고정된 메모리 주소로 변환된다. 이를 정적 바인딩이라 한다.

동적 바인딩

그러나 컴파일 타임에 바인딩 정보를 모르는 경우가 있다. 이럴 때 사용하는 것이 동적 바인딩이다. 가상 함수를 사용할 때 결합 타입이 분명하다면 정적 바인딩을 사용하지만, 기초(부모) 클래스 타입의 포인터 또는 참조를 통하여 호출할 때는 해당 포인터의 실제 객체 정보를 컴파일 타임에는 모르기 때문에 동적 바인딩을 사용한다.

class Parent{
public:
    virtual void Print() {cout << "A 함수\n";
};

class Child : public Parent{
	virtual void Print() {cout << "B 함수\n";
};

int main(){
	Parent* ptr;
    Parent p;
    Child c;
    ptr = &obj_a;
    ptr->Print();
    ptr = &obj_b;
    ptr->Print();
    return 0;
}

실행 결과

A 함수
B 함수

만약 가상함수가 아니라면 정적 바인딩을 사용하게 되고, 따라서 ptr이 c를 가리킴에도 불구하고 기존에 바인딩되었던 parent의 print()함수를 호출하게 된다. 가상 함수를 사용함으로써 포인터의 타입이 아닌 포인터가 실제 가리키는 객체의 타입에 따라 멤버 함수를 선택한다 (동적 바인딩).

가상 함수의 단점

가상 함수 실행 시 C++ 프로그램은 가상 함수 테이블을 통해 적합한 함수의 주소를 호출한다. 따라서 정적 바인딩에 비해 함수의 호출 과정이 복잡해지기 때문에 메모리와 실행 속도에서 약간의 부담을 가진다.

순수 가상 함수

가상 함수는 반드시 재정의해야 하는 함수가 아닌, 재정의가 가능한 함수다. 반면 순수 가상 함수는 반드시 재정의해야하는 함수다. 함수의 내용에 대한 정의, 즉 본체가 없기 때문에 재정의하지 않으면 사용할 수 없다.

virtual func()=0;

추상 클래스

하나 이상의 순수 가상 함수를 포함하고 있는 클래스다. 추상 클래스는 순수 가상 함수를 포함하기 때문에 인스턴스의 생성이 불가하다. 즉 상속을 통해 파생 클래스를 정의하고, 이후 파생 클래스에서 순수 가상 함수를 오버라이딩 한 후에 파생 클래스의 인스턴스 생성이 가능하다.
❗️추상 클래스 타입의 포인터 및 참조는 바로 사용 가능하다.

참고: TCP스쿨

profile
취업준비생/코딩&프로젝트 같이 하실분 연락주세요

0개의 댓글