Programming | 프로그래밍 언어/C++

다중 상속과 가상 상속

gyunnnnnn 2023. 1. 27. 20:06

멤버 함수와 가상 함수의 동작 원리

  • 객체가 생성되면 멤버 변수는 객체 내에 존재한다.
  • 멤버 함수는 메모리의 한 공간에 별도로 위치하고 이 함수가 정의된 클래스의 모든 객체가 이를 공유하는 형태를 취한다.
  • 한 개 이상의 가상 함수를 포함하는 클래스에 대해서는 컴파일러가 가상 함수 테이블을 만든다.
  • 가상 함수 테이블은 객체의 생성과 상관없이 main 함수가 호출되기전 메모리 공간에 할당된다.
  • 가상 함수 테이블은 호출되어야 할 함수의 위치정보를 담고 있는 테이블이다.
class A
{
public:
    virtual void Func() { cout << "A" << endl; }
};

class B : public A
{
public:
    void Func() { cout << "B" << endl; }
};

int main()
{
    A* a = new A();
    a->Func(); // 결과는 A
    A* b = new B();
    b->Func(); // 결과는 B
    return 0;
}
  • A <- B 구조에서 B 클래스의 가상 함수 테이블을 살펴보면, 오버 라이딩된 A클래스의 Func 함수에 대한 정보가 없다.
    • 가상 함수의 호출 원리로 b의 Func 함수를 호출하면 B클래스의 Func 함수가 호출된다.

다중 상속

class A
{
public:
    void Func() { }
};

class B
{
public:
    void Func() { }
};

class C : public A, public B
{
public:
    void Call Func() 
    {
        Func(); // 모호성 존재
        A::Func();
        B::Func();
    }
};
  • 어느 클래스에 선언된 멤버에 접근을 하는지에 대해 모호성이 존재한다.
  • A, B 클래스가 같은 이름의 함수를 가지고 있다면 A::Func();, B::Func();클래스를 명시해야 한다.

가상 상속

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

class Middle1 : virtual public Base
{
public:
    Middle1() : Base() { cout << "Middle1 Constructor" << endl; }
    void Middle1Func()
    {
        BaseFunc();
        cout << "Middle1" << endl;
    }
};

class Middle2 : virtual public Base
{
public:
    Middle2() : Base() { cout << "Middle2 Constructor" << endl;  }
    void Middle2Func()
    {
        BaseFunc();
        cout << "Middle2" << endl;
    }
};

class Last : public Middle1, public Middle2
{
public:
    Last() : Middle1(), Middle2() { cout << "Last Constructor" << endl; }
    void LastFunc()
    {
        Middle1Func();
        Middle2Func();
        BaseFunc();
    }
};

int main()
{
    Last last;
    last.LastFunc();
    return 0;
}
  • 다중 상속을 하면 last 생성 시 base 생성자가 두 번 호출된다.
  • Middle1, Middle2에서 가상 상속을 통해 가상 상속을 하면 base 생성자가 한 번만 호출되도록 할 수 있다.

'Programming | 프로그래밍 언어 > C++' 카테고리의 다른 글

가상 함수  (0) 2023.01.16
C++에서 상속에 대해 정리  (0) 2023.01.13
const, friend, static, mutable, explicit  (0) 2022.11.27
Dangling Pointer  (0) 2022.11.19
C++ STL 벡터, 리스트, 덱 비교  (0) 2022.11.18