Cuantos vptrs se necesitan normalmente para un objeto cuyo clas (child) tiene herencia simple con una clase base que hereda múltiples base1 y base2. ¿Cuál es la estrategia para identificar cuántos vptrs ha proporcionado un objeto que tiene un par de herencia única y herencia múltiple? Aunque el estándar no especifica sobre vptrs, solo quiero saber cómo una implementación implementa la función virtual.¿Cuántos vptr tendrá un objeto de clase (usa herencia única/múltiple)?
Respuesta
¿Por qué te importa? La respuesta simple es suficiente, pero supongo que quieres algo más completo.
Esto no forma parte del estándar, por lo que cualquier implementación es libre de hacer lo que deseen, pero una regla general es que en una implementación que utiliza punteros de tabla virtual, como una aproximación aproximada, para el despacho dinámico que Necesitamos como máximo tantos punteros a tablas virtuales como clases que agregan un nuevo método virtual a la jerarquía. (En algunos casos la tabla virtual puede extenderse, y la base y tipos derivados compartir una única 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
Básicamente cada subobjeto de un tipo que requiere su propio envío dinámico (no se puede reutilizar directamente los padres) necesitaría su propia tabla virtual y vptr.
En realidad, los compiladores combinan diferentes tablas en un solo vtable. Cuando d
agrega una nueva función virtual sobre el conjunto de funciones en b
, el compilador combinará las dos tablas potenciales en una sola al agregar las nuevas ranuras al final de la tabla de visitas, por lo que la tabla de datos para d
será una versión extendida de el vtable para b
con elementos adicionales al final manteniendo compatibilidad binaria (es decir, el d
vtable puede interpretarse como un b
vtable para acceder a los métodos disponibles en b
), y el objeto d
tendrá un solo vptr
.
En el caso de la herencia múltiple, las cosas se vuelven un poco más complicadas ya que cada base necesita tener la misma disposición que un subobjeto del objeto completo que si fuera un objeto separado, por lo que habrá vptrs adicionales apuntando a diferentes regiones en el vtable completo del objeto.
Finalmente, en el caso de la herencia virtual, las cosas se vuelven aún más complicadas, y puede haber múltiples tablas para el mismo objeto completo con el vptr actualizado a medida que la construcción/destrucción evoluciona (las vptr siempre se actualizan a medida que la construcción/destrucción evoluciona, pero sin herencia virtual VPTR apuntará a vtables de la base, mientras que en el caso de la herencia virtual habrá múltiples vtables para el mismo tipo)
la letra pequeña
cualquier cosa con respecto VPTR/no se especifica vtable, por lo esto va a depender del compilador para los detalles finos, pero los casos simples se manejan igual en casi todas las versiones modernas. iler (escribo "casi" por si acaso).
Has sido advertido.
diseño del objeto: la herencia no virtual
Si heredar de clases base, y tienen un VPTR, que, naturalmente, tiene el mayor número heredaron VPTR en su clase.
La pregunta es: ¿Cuándo el compilador agregará un vptr a una clase que ya tiene un vptr heredado?
El compilador tratará de evitar la adición de VPTR redundante:
struct B {
virtual ~B();
};
struct D : B {
virtual void foo();
};
Aquí B
tiene un VPTR, por lo D
no obtiene su propia VPTR, se reutiliza el VPTR existente; el vtable de B
se extiende con una entrada para foo()
. La viable para D
se "deriva" de la viable para B
, pseudo-código:
struct B_vtable {
typeinfo *info; // for typeid, dynamic_cast
void (*destructor)(B*);
};
struct D_vtable : B_vtable {
void (*foo)(D*);
};
la letra pequeña, otra vez: esto es una simplificación de un vtable real, para hacerse una idea.
herencia Virtual
para la herencia única no virtual, casi no hay margen para la variación entre implementaciones. Para la herencia virtual, hay muchas más variaciones entre los compiladores.
struct B2 : virtual A {
};
Hay una conversión B2*
-A*
, por lo que un objeto B2
debe proporcionar esta funcionalidad:
- ya sea con un miembro de
A*
- ya sea con un miembro int:
offset_of_A_from_B2
- cualquiera usando su vptr, almacenando
offset_of_A_from_B2
en el vtable
En general, una clase no reutilizará el vptr de su clase base virtual (pero puede hacerlo en un caso muy especial).
- 1. ¿Cuántos niveles de herencia
- 2. Herencia única en C# - ¿clase de objeto?
- 3. Determinar cuántos campos tiene un objeto Javascript
- 4. ¿Esquemas alternativos para implementar vptr?
- 5. ¿Por qué mi objeto C++ pierde su VPTr
- 6. ¿Cuántos pases sobre el código usa gcc?
- 7. ¿Cómo convertir un objeto ActiveRecord a otra clase cuando se usa STI?
- 8. jquery $ ('. Clase'). Each() ¿cuántos elementos?
- 9. ¿Cuántos bytes usa Oracle al almacenar un solo carácter?
- 10. Herencia de clase en Python
- 11. C# Clase Herencia
- 12. Herencia de clase en Javascript
- 13. C# campo estático clase abstracta herencia
- 14. Con 2 servidores web, ¿una clase singleton tendrá 2 instancias?
- 15. ¿Cuándo una clase tendrá alguna vez más de un inicializador designado?
- 16. ¿Por qué se requiere un vptr cuando la clase derivada no anula la función virtual?
- 17. Herencia de clase de tipo herencia múltiple en ruby
- 18. ¿Herencia de tabla única o herencia de tabla de clase?
- 19. ¿Cómo se usa HttpURLConnection para enviar un objeto serializado a un Servlet de la clase Java?
- 20. ¿Cuántos métodos predeterminados tiene una clase?
- 21. ¿Un hash SHA256 siempre tendrá 64 caracteres?
- 22. Decoradores de Python y herencia de clase
- 23. C++ clase Singleton - buenas prácticas de herencia
- 24. conjunto de clases herencia después delcaration clase o la herencia de clases configuración en clase const_set
- 25. Selenio cómo seleccionar un objeto por clase
- 26. WCF Serialización con herencia de objeto?
- 27. Herencia de clase de caso de Scala
- 28. Java objeto serialización y la herencia
- 29. implementando el operador == cuando se usa la herencia
- 30. ¿El caché del navegador tendrá una imagen de fondo CSS si no se usa?
"' struct d: b {barra virtual();}; // vtable extra, necesita b.vptr y d.vptr' "No creo que haya ningún compilador que presente más de un vptr en una clase con SI no virtual. – curiousguy