반응형

 

멤버함수 동작원리

- C++의 객체의 멤버변수는 객체 내에 존재하지만 멤버함수는 다음과 같은 관계를 갖는다.

  • 멤버함수는 메모리의 한 공간에 별도로 위치한다.
  • 멤버함수가 정의된 클래스의 모든 객체가 이를 공유하는 형태를 취한다. (함수포인터를 생각하면 이해하기 편하다.)

 

 

 

 

가상함수 동작원리

- 예제 소스는 다음과 같다.

#include <iostream>
using namespace std;

class Parent
{
public:
    virtual void Func_1()
    {
        cout << "Parent : Func_1" << endl;
    }
    virtual void Func_2()
    {
        cout << "Parent : Func_2" << endl;
    }
};

class Son : public Parent
{
public:
    virtual void Func_1()
    {
        cout << "Son : Func_1" << endl;
    }
    void Func_3()
    {
        cout << "Son : Func_3" << endl;
    }
};

void main()
{
    Parent* parentPtr = new Parent();
    parentPtr->Func_1();
    
    Son* sonPtr = new Son();
    sonPtr->Func_1();
    
    //결과
    //Parent : Func_1
    //Son : Func_1
}

- 위의 코드에서 가상함수를 확인할 수 있는데, 한 개 이상의 가상함수를 포함하는 클래스에 대해서는 컴파일러가 '가상함수 테이블'이라는 것을 만든다. (V-Table이라고도 한다.)

- 가상함수 테이블은 Key와 Value를 가지고 있다.

  • Key : 호출하고자 하는 함수를 구분지어주는 구분자의 역할을 한다.
  • Value : 구분자에 해당하는 함수의 주소정보를 알려주는 역할을 한다.

- 따라서, Parent 클래스와 Son의 클래스의 가상함수 테이블은 다음과 같이 구성된다.

  • Parent 객체의 Func_1 함수를 호출하는 경우, Parent 테이블에서 첫 번쨰 행의 정보를 참조하여 Func_1 함수를 호출하게 된다.
  • Son 객체의 테이블을에서는 오버라이딩 된 가상함수의 Func_1에 대한 정보가 존재하지 않는다.
  • 즉, 오버라이딩 된 가상함수의 주소정보는 자식 클래스의 가상함수 테이블에 포함되지 않는다.
  • 결과적으로 오버라이딩된 가상함수를 호출하면, 가장 마지막에 오버라이딩을 한 자식 클래스의 멤버함수가 호출되게된다.

 

 

 

 

가상함수 테이블이 참조되는 방식

- 예제 소스가 실행되면, main함수가 호출되기 전에 가상함수 테이블이 메모리 공간에 할당된다.

  ※ 참고로 가상함수 테이블은 객체의 생성과 상관없이 메모리 공간에 할당된다. (가상함수 테이블이 멤버함수의 호출에 사용되는 일종의 데이터이기 때문.)

- main 함수가 호출되어 객체가 생성되고 나면, 각 Parent, Son 객체는 해당 클래스의 가상함수 테이블의 주소값이 저장된다.

  ※ 가상함수 테이블의 주소값은 우리가 직접 참조할수 있는 주소값이 아니고, 내부적 필요에 의해 참조되는 주소값이다.

- Parent 객체에서 Func_1함수를 호출하게되는 과정.

  • Parent 객체가 Parent 클래스의 가상함수 테이블 참조 → 100번지에 위치한 함수 실행

- Son 객체에서 Func_1함수를 호출하게 되는 과정.

  • Son객체가 Son 클래스의 가상함수 테이블 참조 → 200번지에 위치한 함수 실행

 

 

 

 

가상함수 테이블에 의한 속도의 저하

- 클래스에 가상함수가 포함되어 가상함수 테이블이 생성되면, 이 테이블을 참조하여 호출될 함수가 결정되기 때문에 실행속도가 감소하게된다.

- 하지만 극히 미미하고 속도차이를 감안하더라도 많은 장점을 제공하기 때문에 유용하게 활용되는것이다.

 

반응형

'Stack > C++' 카테고리의 다른 글

C++ friend  (0) 2021.12.05
C++ 다중상속  (0) 2021.11.22
C++ 순수 가상함수, 추상 클래스  (0) 2021.11.11
C++ 업캐스팅, 오버라이딩, 가상함수  (0) 2021.11.08
C++ 클래스 상속  (0) 2021.11.04

+ Recent posts