멤버함수와 동작원리


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


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


virtual로 선언된 가상함수를 하나 이상 포함하는 클래스에대해서는 컴파일러가 가상함수테이블이라는것을 생성한다. 이를 V- Table이라고하는데 , 이는 실제 호출되어야할 함수의 위치정보를 담고있는 테이블이다. key는 호출하고자하는 함수를 구분지어주는 역할 ,  value는 구분자에 해당하는 함수의 주소정보를 알려주는 역할을한다. 


ex)

key - void AAA::Func1()

value - 0x1024


이때 , 오버라이딩된 가상함수의 주소정보는 유도클래스의 가상함수테이블에 포함되지않는다. 때문에 오버라이딩된 가상함수를 호출하면 무조건 가장 마지막에 오버라이딩한 유도클래스의 멤버함수가 호출된다. 


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


가상함수테이블은 객체의 생성과 상관없이 메모리공간에 할당된다 . AAA 객체에는 AAA 클래스의 가상함수테이블의 주소값이 저장되고 , BBB 객체에는 BBB 클래스의 가상함수 테이블의 주소값이 저장된다 . 즉 , 가상함수를 하나이상 멤버로 가지는 클래스의 객체에는 가상함수 테이블의 주소값이 저장된다.

이때 , 가상함수테이블을 참조하여 호출될함수를 결정하기때문에 , 속도저하가 있지만 가상함수는 많은 장점을 제공하기때문에 유용하게 사용된다.


다중상속


다중상속이란 둘 이상의 클래스를 동시에 상속하는것을 말한다. 다중상속은 많은 문제를 야기할수있으므로 사용을 자제하고 사용할때도 최대한 제한적으로 사용해야한다.


다중상속의 모호성


다중상속의 대상이되는 두 기초클래스에 같은이름의 멤버가 존재하는경우 , 어떤 기초클래스에 선언된 멤버를 호출할것인지 모호해진다. 이를 해결하기위해서는 어느 클래스에 정의된 함수의 호출을 원하는지 직접 명시해야한다.


ex)

BaseOne :: SimpleFunc;

BaseTwo :: SimpleFunc;


가상상속


class Base

class MiddleDerivedOne : virtual public Base

class MiddleDerivedTwo : virtual public Base

class LastDerived :  public MiddleDerivedOne , public MiddleDerivedTwo


위와같이 선언되었을때 , virtual 선언이없다면, LastDerived 객체가 생성될때 두개의 Base 클래스 멤버가 존재하게되고 , 이를 해결하기위해서는 어느클래스를 통해서 간접상속한 Base 클래스의 멤버를 호출할것인지 명시해야한다. virtual 선언을통해 Base 클래스를 한번만 상속하게만듬으로서 , 이러한 불편을 해소할 수 있다.



+ Recent posts