C/C++ 관련 헷갈리기 쉬운 것 정리6(저장용,메모용, 윤성우 열혈 C++ 프로그래밍 정리 CH 9)

RisingJade의 개발기록·2022년 2월 22일
0

Chapter 9. 가상(Virtual)의 원리와 다중상속

09-1. 멤버함수와 가상함수의 동작원리

객체 안에 정말로 멤버함수가 존재하는가?

  • 객체가 생성되면 멤버변수는 객체 내에 존재하지만, 멤버함수는 메모리의 한 공간에 별도로 위치하고선, 이함수가 정의된 클래스의 모든 객체가 이를 공유하는 형태를 취한다.

가상함수의 동작원리와 가상함수 테이블

  • 한 개 이상의 가상함수를 포함하는 클래스에 대해서는 컴파일러가 다음 그림과 같은 형태의 '가상함수 테이블'이라는 것을 만든다. 이를 간단히 'V-Table'(가상함수 테이블)이라고 하는데, 이는 실제 호출되어야 할 함수의 위치정보를 담고 있는 테이블이다.
  • 각 class마다 위와 같은 가상함수 테이블을 갖게 된다.
  • 실제 작동은 가상 함수테이블에 있는 주소로 가서 함수를 실행하게 된다. (virtual 함수 실행시, 포인터안에 담긴 '객체' 안에 있는 Vtable pointer로 vtable에 접근하여 해당 객체에 맞는 함수를 실행하게 된다.)
  • main함수가 호출되기 이전에 위의 그림처럼 가상함수 테이블이 메모리 공간에 할당된다.(참고로 가상함수 테이블은 객체의 생성과 상관없이 메모리 공간(바이너리 rdata)에 할당된다. 이는 가상함수 테이블이 멤버함수의 호출에 사용되는 일종에 데이터이기 때문이다.)

보면 알겠지만, 가상 함수를 쓸데마다 가상함수 테이블이 생성되고, 또 이 테이블을 참조하여 호출될 함수가 결정되기 때문 실행속도가 감소한다. 하지만 그 속도차가 미미하고 가상함수는 많은 장점을 제공하기 때문에 유용하게 사용된다.


09-2. 다중상속(Multiple Inheritance)에 대한 이해

다중상속에 대한 견해

"일반적인 경우에서 다중상속은 다양한 문제를 동반한다. 따라서 가급적 사용하지 않아야 함에는 동의를 한다. 그러나 예외적으로 매우 제한적인 사용까지 부정할 필요는 없다고 본다."

다중상속의 기본방법

class BaseOne {
...
}

class BaseTwo {
...
}

class MultiDerived : public BaseOne, protected BaseTwo{
 public:
    void complexFunc(){
    	SimpleFuncFromBaseOne();
        SimpleFuncFromBaseTwo();
    }
}

다중상속의 모호성

같은 이름의 멤버함수 혹은 멤버변수가 있는 클래스들을 다중상속 받을 경우 반드시 어느 클래스것을 사용할지 AAA::num이런식으로 명시해야 한다.

가상 상속(Virtual Inheritance)

  • 두개 이상의 상속을 받을때, 그 둘의 기초 클래스가 같을 경우 생성자가 한번만 생성되야하는 것이 맞지만, 그냥 생성자를 만들면 2번 호출하게 되거나, 어느 클래스에서 최초 부모클래스를 부를지 몰라 에러가 난다. 따라서 가상 상속을 통해 1번만 호출이 가능하다.
class base{
...
}
class drivenOne: virtual public base {// virtaul로 선언함으로서 같은 부모 생성자가 하나만 호출된다.
...
}
class drivenTwo: virtual public base {// virtaul로 선언함으로서 같은 부모 생성자가 하나만 호출된다.
...
}
class lastDriven: public drivenOne, public drivenTwo {
...
}
profile
언제나 감사하며 살자!

0개의 댓글