본문으로 바로가기






C++에서 virtual 키워드가 어떤 목적으로 쓰이는지 알고계십니까? 크게 두가지로 나누자면 상속관계에서 다중 상속의 문제점을 해결하고, 하위 클래스에서 함수를 오버라이딩(overriding)하기 위해 사용됩니다. 아래에서 순서대로 설명하겠습니다.




# virtual 1 : 클래스 상속과 오버라이딩(overriding)

부모클래스를 상속받고 부모클래스에 정의된 함수를 오버라이딩하려할 때, 하위 클래스의 객체에서 재정의된 함수를 호출하기 위해서 vitual 키워드를 사용해야합니다. 그 이유는 virtual 키워드를 사용하지 않은 상황에서 컴파일시 프로그램에 부모클래스의 함수의 호출 주소가 저장되며(정적 바인딩의 개념) 실제 호출시에 저장된 부모클래스의 함수가 호출되기 때문입니다. 하지만 virtual 키워드를 사용함으로써 런타임시 지정되는 함수를 호출 할 수 있게 해줄 수 있습니다. 전자와 후자의 내용을 아래에서 직접 실행을 통해 비교해보겠습니다.


위의 두 사진을 통해 virtual 키워드의 사용의 차이를 알 수 있을겁니다. 이것은 상속과 다형성을 활용할 때 매우 중요하게 작용합니다. 자세하게 궁금한 것은 직접 소스코드를 작성해 확인하고 궁금한 점은 댓글로 남겨주시면 반드시 답글 달아드리겠습니다.




# virtual 2 : 클래스 상속과 다중 상속

객체지향 프로그래밍을 하다보면 클래스를 만들어 상속해야하는 상황이 빈번히 발생합니다. 그 이유는 부모클래스에서 정의한 멤버변수나 멤버 함수를 자식클래스에서 사용해야하기 때문이죠.





위의 사진에서는 Middle1Middle2 클래스가 Top 클래스를 상속받고 있고, Bottom 클래스가 Middle1Middle2 클래스를 상속받고 있습니다. 그리고 Top에 정의된 print 함수를 재정의하여 최종적으로 Bottom에서 사용할 계획입니다. 미리 말씀드리자면 아래의 코드는 정상적으로 작동하지 않는 코드입니다. 왜그런지 생각해보면서 넘어가시길 바랍니다.




다형성을 위해 line.128과 같이 객체를 할당하려는데 다음과 같은 오류가 납니다. "기본 클래스 Top이(가) 모호합니다." 무슨 뜻일까요? 현재 BottomMidlle1, 2를 모두 상속받고 있고 그들은 서로 다른 인스턴스의 Top을 갖기 때문에 재정의한 print 함수를 사용함에 있어서 Middle1Middle2 중 어느 클래스의 부모(Top)으로부터 상속받은 함수를 사용해야할지 모르는 것입니다. 이를 해결하기 위해서는 Top 클래스를 상속 받을 때 vitual 키워드를 써줌으로써 같은 객체를 사용하도록 일종의 동기화를 해줄 수 있습니다. 아래 코드는 vitual 키워드를 사용해 해결한 부분과 테스트를 위한 추가적인 코드가 추가되었습니다.



위 소스코드에서는 virtual을 통해 다중 상속 및 함수 사용에 대한 모호함을 해결했고, 테스트를 위해 최 상위 클래스에 int st 라는 변수를 생성해 하위 클래스에서 사용했습니다. 간단히 설명드리자면 Bottom 클래스에 대한 인스턴스를 생성했고, Bottom 클래스는 Middle1Middle2를 상속받고 있기 때문에 Middle1Middle2의 생성자를 거치게 되고, Middle1의 생성자를 거치면서 0값을 가졌던 st변수가 1이 되고 Bottom 인스턴스의 print 함수를 호출했을 때 st의 값은 1이 출력됩니다. 출력물은 아래와 같습니다.



하지만 인스턴스를 Bottom이 아닌 Middle2로 지정하여 생성하게 되면 Middle1의 생성자를 거치지 않기 때문에 print 함수를 호출하면 st의 값은 0이 출력됩니다.