Ch13 상속
상속
대부분의 이야기는 다 아는 이야기일 것임.
헷갈리거나 다시 정리하기 좋은 부분만 정리함.
동적결합과 가상함수
함수를 호출하면 바로 다음줄의 코드가 아니라 멀리 떨어진 어떤 블럭의 코드를 실행 해야함.
이를 컴파일러 가 해주면 정적결합(Static Binding) 이라고 하고 런타임 에서 연결되면 동적결합(Dynamic Binding, Lately Binding) 이라고 함.
동적결합은 가상함수에서 쓰임(다른경우가 또 있는진 몰겠음)
당연히 동적결합이 더느림.
Virtual Function Table
c++ 에서 동적결합이 어떻게 동작하는가? 혹은 가상함수가 어떻게 동작하는가? 에 대한 답.
사실 컴파일러가 다르게 구현해도 결과만 같으면 상관이 없는데 대개 이렇게 구현한다함.
가상함수가 정의된 클래스는 virtual table 을 가지며 sizeof 로 직접 확인 가능함.
8
16
환경에 따라 다른데 Visual Studio 64bit 환경에서 돌리면 저렇게 나옴.
위 결과는 정확하게 말하면 Virtual Function Table 을 가리키는 VPointer 가 클래스의 멤버로 생기고 이게 위의 sizeof
에서 잡힌 것임.
VPointer 는 가상함수가 적용된 클래스마다 컴파일러가 생성한 VTable 의 주소를 가짐.
VTable 은 RTTI 정보를 가지며 Function Name 등을 인덱스로 해당 Function 의 시작 주소를 연결해줌. ( 뭐가 인덱스인지는 컴파일러 구현하기 나름임 )
가상함수 주의점
앞에서 Function Name 으로 함수의 주소를 찾아서 그런지는 모르겠지만 함수의 이름은 같은데 변수만 가지고 장난치는 오버로딩이 가상함수에선 민감함.
-
가상함수의 파라미터를 바꿀 수 없음. 만약 바꾸면 그건 override 가 아니라 새로운 함수를 만드는거임. 이때 예외가 있다면 리턴형에 한해서 기초클래스의 참조나 포인터면 파생클래스의 참조나 포인터가 가능함(covarriance).
-
가상함수가 오버로딩되어 있을 때, 하나만 override 할 수 없고 모든 버전을 다 해야함. 하나만 하면 나머지는 호출할 수 없게 됨.
추상 클래스
순수가상함수가 하나라도 있으면 추상클래스. 필수는 아니고 class AAA abstract
이렇게 표시가 권고됨.
추상클래스는 파생클래스가 순수가상함수가 전부 오버라이드 하지 않으면 객체가 될 수 없음.
인터페이스
-
순수가상함수로만 이루어지고
-
생성자 소멸자 연산자, static 없고
-
데이터 멤버 없음
다른 종류의 인터페이스 끼리는 서로 겹칠일이 없어서 다중상속이 용이해져서 쓴다고 함.
컴파일러가 자동으로 생성하는 멤버함수
디폴트 생성자, 디폴트 소멸자, 복사생성자, 복사대입연산자, 이동생성자, 이동대입연산자
reference 나 const 의 멤버가 있는 경우 복사대입연산자가 자동으로 안만들어짐.
이렇듯 모든 경우에서 다 만들어지는건 아님.
동적할당을 하는 클래스
Rule Of Five 라고 깊은 복사할 때 따르라는 규칙? 비슷한게 있음.
복사 생성, 이동 생성, 복사대입연산, 이동대입연산, 소멸자 중에 하나라도 명시적으로 선언하면 다 해라는 그런건데 표준은 아님. 깊은 복사 까먹지 말라는 지침 같은거.
댓글남기기