때로는 일부 코드/다이어그램을 볼 필요가 있습니다.이 표준에 대한 구현 세부 사항에 대한 언급은 없습니다.모든
먼저, C++의 메소드를 구현하는 방법을 보자 :
struct Base
{
void foo();
};
이 유사합니다
struct Base {};
void Base_foo(Base& b);
그리고 사실
, 당신은 디버거 내에서 메서드 호출을 볼 때 첫 번째 매개 변수로 종종
this
인수가 표시됩니다. 때로 암시 적 매개 변수라고도합니다.
이제 가상 테이블을 참조하십시오. C와 C++에서 함수 포인터를 사용할 수 있습니다. 상속에에,
void func()
{
Base b;
(*gBaseVTable.mSetter)(b, 3);
std::cout << (*gBaseVTable.mGetter)(b) << std::endl; // print 3
}
지금 :
struct Base
{
int a;
};
void Base_set(Base& b, int i) { b.a = i; }
int Base_get(Base const& b) { return b.a; }
struct BaseVTable
{
typedef void (*setter_t)(Base&, int);
typedef int (*getter_t)(Base const&);
setter_t mSetter;
getter_t mGetter;
BaseVTable(setter_t s, getter_t g): mSetter(s), mGetter(g) {}
} gBaseVTable(&Base_set, &Base_get);
지금 내가 뭔가를 할 수 있습니다의 vtable은 본질적 기능에 대한 포인터의 테이블입니다.
void func()
{
Derived d;
(*gDerivedBaseVTable.mSetter)(d, 3);
std::cout << (*gDerivedBaseVTable.mGetter)(d) << std::endl; // print 4
}
을하지만 어떻게이 문제를 자동화 :의 다른 구조
struct Derived: Base {}; // yeah, Base does not have a virtual destructor... shh
void Derived_set(Derived& d, int i) { d.a = i+1; }
struct DerivedBaseVTable
{
typedef void (*setter_t)(Derived&,int);
typedef BaseVTable::getter_t getter_t;
setter_t mSetter;
getter_t mGetter;
DerivedBaseVTable(setter_t s, getter_t g): mSetter(s), mGetter(g) {}
} gDerivedBaseVTable(&Derived_set, &Base_get);
그리고 사용을 만들어 보자?
- 당신은 비록 당신이 정말로 액세스 할 수 없습니다 (첫 번째 속성으로 vtable에 대한 포인터를 포함 적어도 하나의 가상 함수를
- 클래스의 각 인스턴스를 가진 클래스 당 VTABLE의 인스턴스가 필요합니다 그것 스스로)
이제 다중 상속의 경우 어떻게됩니까? 음, 상속은 매우 메모리 레이아웃의 용어의 구성과 같다 :
이
| Derived |
| BaseA | BaseB |
| vpointer | field1 | field2 | padding? | vpointer | field1 | field2 | padding? |
따라서 MostDerived
2 개 가상 테이블이있을 것 하나는 BaseB
에서 방법을 변경 BaseA
하나의 방법을 변경할 수 있습니다.
순수 가상 기능은 일반적으로 해당 필드에서 null 포인터 (간단히)로 표시됩니다.
그리고 마지막으로, 생성과 소멸 :
건설
BaseA
가 구성된다 : 먼저 vpointer 초기화 한 후 속성, 다음 생성자의 본문 구성되어
BaseB
을 실행 : vpointer, 특성, 본문
Derived
구성 : vpointer (둘 다), 특성, 본문 바꾸기
파괴
Derived is destructed
: 몸
BaseA
가 파괴되는 속성 : 소멸자의 몸은, 기본 다시
BaseB
가 파괴되어 vpointers를 넣어 속성을 파괴 몸,
속성
꽤 포괄적이라고 생각합니다. 주위의 일부 C++ 전문가가 이것을 검토하고 I ha를 확인할 수 있다면 기쁠 것입니다. 바보 같은 실수는하지 마라. 또한 누락 된 부분이 있으면 추가 할 수있어서 기쁩니다.
정말 포괄적 인 답변입니다! 고마워요! – Bruce
가상 상속 중 어떤 일이 발생합니까? 그리고 가상 상속 후 Bat가 (vpointer, Mammal, vpointer, WingedAnimal, Bat, Animal)이된다는 것을 어떻게 설명합니까? – Bruce
여기서 '박쥐'는 오류입니다 (무한 재귀를 일으킴). 무시하십시오. '가상'상속의 경우 가상으로 상속받은 클래스는 (가장 많이 파생 된 클래스에 의해) 한번만 인스턴스화되지만'Mammal'과'WingedAnimal' 부분 전에 분명하게 인스턴스화됩니다. –