티스토리 뷰

가상함수 테이블

- 실제로는 맴버변수는 클래스 내부에 존재하지만, 맴버함수는 별도의 메모리 공간에 존재하고 클래스는 그 메모리의 주소값을 기억한다.

 

- 한 개 이상의 가상함수를 포함하는 클래스에 대해서 컴파일러는 가상함수 테이블을 만든다.

  가상함수 테이블이란 실제 호출되어야 할 함수의 위치 정보를 담고 있는 테이블이고, key-value 형태로 이루어져 있으며,

  key값은 함수의 이름, value값은 함수의 주소정보를 담고 있다.

 

- 유도 클래스의 가상함수 테이블에는 오버라이딩 된 가상함수의 주소정보는 포함되지 않는다. 

  따라서 오버라이딩 된 가상함수를 호출하면, 가장 마지막에 오버라이딩을 한 유도 클래스의 맴버함수가 호출된다. 

 

가상함수 테이블은 main 함수 호출 이전에 생성되고, 객체의 생성 여부와 상관없이 무조건 만들어진다. 

 

가상상속

- mid1, mid2 클래스가 base클래스를 상속하고, last 클래스가 mid1, mid2를 다중상속하는 상황을 생각해보면, 

  last 클래스 내부에는 두개의 base 클래스 맴버가 존재하게 된다. (mid1, mid2가 둘 다 base 를 상속하고 있으므로) 

  이런 경우 맴버함수 앞에 mid1::, mid2:: 이런 식으로 어느 클래스를 통해서 간접 상속한 base 클래스의 맴버함수를 호출할 것인지 명시    해야 한다.

 

- 하지만 이런 경우 base 클래스의 맴버는 last 클래스에 하나만 존재해도 되는 경우다. 

  이럴때 base 클래스를 한 번만 상속하게끔 하는것이 가상상속이다.

 

- mid1이 base 클래스를 가상 상속하고, mid2가 base 클래스를 가상상속하게 되면

  last 클래스가 mid1, mid2를 다중상속했을때 last 클래스에는 base 클래스의 맴버가 하나씩만 존재하게 된다.

 

#include <iostream>
using namespace std;

class Base
{
public:
    Base() { cout << "Base Constructor" << endl; }
    void SimpleFunc() { cout << "BaseOne" << endl; }
};

class Mid1 : virtual public Base // Base를 가상상속
{
public:
    Mid1() : Base()
    {
        cout << "Mid1 Constructor" << endl;
    }
    void MiddleFuncOne()
    {
        SimpleFunc(); // base class의 맴버
        cout << "Mid1" << endl;
    }
};

class Mid2 : virtual public Base
{
public:
    Mid2() : Base()
    {
        cout << "Mid2 Constructor" << endl;
    }
    void MiddleFuncTwo()
    {
        SimpleFunc();
        cout << "Mid2" << endl;
    }
};

class Last: public Mid1, public Mid2
{
public:
    Last() : Mid1(), Mid2()
    {
        cout << "Last Constructor" << endl;
    }
    void ComplexFunc()
    {
        MiddleFuncOne();
        MiddleFuncTwo();
        // Mid1, Mid2가 Base를 가상상속 했으므로 Last에는 Base의 맴버가 하나씩만 존재한다
        SimpleFunc();
    }
};

int main()
{
    cout << "객체생성 전 ... " << endl;
    Last last;
    cout << "객체생성 후 ... " << endl;
    last.ComplexFunc();
}

실행결과:

실행결과를 보면 Last 객체를 생성했을때 Base 클래스의 생성자가 1번만 호출됐다.

이는 Mid1, Mid2가 Base 클래스를 가상상속했기 때문에 Last 클래스에 Base 클래스의 맴버가 1개만 존재하기 때문이다. 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함