clas (child)가 base1과 base2를 상속하는 기본 클래스를 가진 단일 상속을 가진 객체에 보통 얼마나 많은 vptrs가 필요한가? 객체가 제공 한 vptr의 수를 확인하는 전략은 단일 상속과 다중 상속이 있습니다. 표준은 vptrs에 대해 지정하지 않지만 구현이 가상 함수 구현을 수행하는 방법을 알고 싶습니다.클래스의 객체 (단일/다중 상속을 사용)의 vptr은 몇 개입니까?
답변
왜 신경 씁니까? 간단한 대답은 입니다.이긴하지만, 좀 더 완벽한 것을 원합니다.
이것은 표준의 일부가 아니므로 임의의 구현은 원하는대로 자유롭게 수행 할 수 있지만 일반적인 경험적 규칙에 따라 가상 테이블 포인터를 사용하는 구현에서 0을 근사치로 사용하여 동적 디스패치를 수행 할 수 있습니다. 계층에 새로운 가상 메소드를 추가하는 클래스가 있으므로 가상 테이블에 대한 포인터가 많아야합니다. 필요 (어떤 경우에는 가상 테이블 확장, 그리고베이스와 파생 된 형식은 하나의 vptr
공유 할 수 있습니다) 기본적으로
// some examples:
struct a { void foo(); }; // no need for virtual table
struct b : a { virtual foo1(); }; // need vtable, and vptr
struct c : b { void bar(); }; // no extra virtual table, 1 vptr (b) suffices
struct d : b { virtual bar(); }; // extra vtable, need b.vptr and d.vptr
struct e : d, b {}; // 3 vptr, 2 for the d subobject and one for
// the additional b
struct f : virtual b {};
struct g : virtual b {};
struct h : f, g {}; // single vptr, only b needs vtable and
// there is a single b
자신의 동적 파견 (직접 부모를 다시 사용할 수 없습니다)을 필요로하는 유형의 각 하위 객체를 자체 가상 테이블 및 vptr.
실제로 컴파일러는 서로 다른 vtable을 단일 vtable로 병합합니다. d
이 b
에있는 함수 세트를 통해 새로운 가상 함수를 추가하면 컴파일러는 새로운 슬롯을 vtable의 끝에 추가하여 잠재적 인 두 테이블을 하나로 병합하므로 d
의 vtable은 다음과 같은 확장 버전이됩니다. 바이너리 호환성을 유지하는 끝에 여분의 요소가있는 b
의 vtable (d
vtable은 b
에서 사용할 수있는 메서드에 액세스하기 위해 b
vtable로 해석 될 수 있음) d
개체는 vptr
을 갖습니다.
다중 상속의 경우 개별 객체 인 경우보다 완전한 객체의 하위 객체와 동일한 레이아웃을 갖는 각 기본 객체가 필요하기 때문에 좀 더 복잡해집니다. 따라서 다른 영역을 가리키는 추가 vptrs가있게됩니다 전체 개체의 vtable.
마지막으로 가상 상속의 경우 상황이 훨씬 복잡해지고 동일한 완성 된 개체에 대해 vtr이 여러 개있을 수 있습니다. 건설/파괴가 진행됨에 따라 vptr이 업데이트됩니다 (vptr은 건설/파괴가 진행됨에 따라 항상 업데이트되지만 가상 상속의 경우에는 동일한 유형의 여러 vtable을)
아무것도에 대한 vptr에서/VTABLE이 지정되지 않은 미세 인쇄, 그래서이있을 것 동안 가상 상속없이 vptr에서이 기지의 vtable을 가리 킵니다 이것은 훌륭한 세부 사항에 대한 컴파일러 의존성이 될 것입니다. 그러나 단순한 경우는 거의 모든 현대 컴파일러에 의해 동일하게 처리됩니다 iler (필자는 "거의"라고 쓴다.)
경고를 받았습니다.
개체 레이아웃 : 비 가상 상속
당신이 기본 클래스에서 상속, 그리고 그들이 vptr에서이 있다면, 당신은 자연스럽게 많은 이 클래스에 vptr에서을 상속합니다.
질문 : 컴파일러가 상속 된 vptr이 이미있는 클래스에 vptr을 언제 추가합니까?
컴파일러는 중복 vptr에서 추가 피하기 위해 노력할 것 : 여기 B
struct B {
virtual ~B();
};
struct D : B {
virtual void foo();
};
은 vptr에서이 있으므로 D
가 자신의 vptr에서 얻을하지 않습니다, 그것은 기존의 vptr에서이 재사용을; B
의 vtable은 foo()
에 대한 항목으로 확장됩니다. D
의 VTABLE은 B
, 의사 코드의 VTABLE에서 "파생"입니다 :
struct B_vtable {
typeinfo *info; // for typeid, dynamic_cast
void (*destructor)(B*);
};
struct D_vtable : B_vtable {
void (*foo)(D*);
};
글씨는 다시이 실제의 vtable의 단순화, 아이디어를 얻을 수 있습니다.
이 아닌 가상의 단일 상속 가상 상속
는 구현 사이의 변화에 대한 거의 여지가 없다. 가상 상속의 경우 컴파일러간에 훨씬 더 많은 변형이 있습니다.
struct B2 : virtual A {
};
A*
-
B2*
에서 변환이
, 그래서 B2
객체는이 기능을 제공해야 하나 offset_of_A_from_B2
A*
회원- 중 하나를 vptr을 사용하여 vtable에
offset_of_A_from_B2
을 저장하여
일반적으로 클래스는 이 아니며은 가상 기본 클래스의 vptr을 다시 사용합니다 (그러나 매우 특별한 경우도 있음).
- 1. 밖에있는 GPU는 몇 개입니까?
- 2. "큰"데이터 세트는 몇 개입니까?
- 3. 실행중인 CLR 인스턴스는 몇 개입니까?
- 4. JSON. 허용되는 요소는 몇 개입니까?
- 5. 아직 야생에있는 Microsoft JVM은 몇 개입니까?
- 6. 도메인에 대해 쿠키 수는 몇 개입니까?
- 7. iPhone 시뮬레이터에서 지원하는 국제 언어는 몇 개입니까?
- 8. JS가 활성화 된 봇 수는 몇 개입니까?
- 9. n 비트 정수의 1은 몇 개입니까?
- 10. 전자 상거래를 지원할 데이터베이스는 몇 개입니까?
- 11. 상속을 사용하여 새 객체 만들기
- 12. 상속을 사용하는 데있어 이해하기 쉬운 몇 가지 예가 있습니까?
- 13. 내 앱의 경우 최적의 스레드 수는 몇 개입니까?
- 14. Resharper는 WPF에서 Window 클래스의 중복 상속을 제거합니다.
- 15. NHibernate 세션 : 몇 개입니까? 언제 만들까요? 언제 닫을까요?
- 16. iphone을 지원하는 동시 (동시) 네트워크 연결은 몇 개입니까?
- 17. iphone/objective-c dev에 너무 많은 스레드가 몇 개입니까?
- 18. PHP에서 정의 할 수있는 최대 상수는 몇 개입니까?
- 19. 각 정렬 알고리즘에서 스와핑 및 컴마네이션은 몇 개입니까?
- 20. AppDomain 당 허용되는 app.config 파일 수는 몇 개입니까?
- 21. 배열의 요소 중 null이 아닌 것은 몇 개입니까? I는이 같은
- 22. ObjC : 헤더 파일에서 상속을 지정해야합니까? ObjC 객체
- 23. 다른 클래스의 Dealloc 객체
- 24. 사용의 HttpWebRequest는
- 25. 사용의 jQuery의 XPath 셀렉터
- 26. CSS3 배경이 여러 개입니까?
- 27. 둥근 모서리가 두 개입니까?
- 28. 다른 클래스의 객체 속성을 얻으십시오
- 29. 다른 클래스의 배열에 객체 삽입
- 30. ActionScript : 값 객체 클래스의 생성자
"struct d : b {가상 바();} // 추가 vtable, 필요 b.vptr 및 d.vptr'"클래스에 둘 이상의 vptr을 도입하는 컴파일러가 없다고 생각합니다. 가상이 아닌 SI와 – curiousguy