fbpx
Wikipedia

Herencia virtual

En C++, herencia virtual es un tipo de herencia que solventa algunos de los problemas causados por la herencia múltiple (particularmente, el "problema del diamante") mediante la aclaración de la ambigüedad sobre qué miembros de clases padre usar. Es usada cuando la herencia está representando restricciones de un conjunto más que la composición de partes. Una clase base multi-heredada se denota como virtual con la palabra clave virtual.

El problema

Considerando la siguiente jerarquía de clase.

 class Animal {  virtual void Come();  };    class Mamífero : public Animal {  public:  virtual Color GetColorPelo();  };  class AnimalConAlas : public Animal {  public:  virtual void Aletea();  };    // Un murciélago es un mamífero con alas  class Murciélago : public Mamífero, public AnimalConAlas {}; 

Pero, ¿cómo Come() un murciélago? Como se ha declarado arriba, una llamada a Murciélago.Come() es ambiguo. Debería llamarse a Murciélago.AnimalConAlas::Come() o a Murciélago.Mamífero::Come(). El problema es que la semántica de la herencia múltiple convencional no modela la realidad. En un sentido, un Animal es Animal solo una vez; un Murciélago es un Mamífero y un AnimalConAlas, pero un Murciélago es tan Animal por ser Mamífero como por ser AnimalConAlas.

Esta situación es llamada a veces herencia en diamante y es un problema que la herencia virtual intenta, en parte, solventar.

Representación de clases

Antes de seguir es útil tener en cuenta cómo se representan las clases en C++. Concretamente, la herencia es solo cuestión de poner la clase padre y la clase hija una detrás de la otra en memoria. De esta forma Murciélago es realmente (Animal, Mamífero, Animal, AnimalConAlas, Murciélago), lo que hace que se duplique Animal, causando la ambigüedad.

Solución

Podemos redeclarar nuestras clases de la forma siguiente:

 // Dos clases heredando virtualmente de Animal:  class Mamífero : public virtual Animal {  public:  virtual Color GetColorPelo();  };  class AnimalConAlas : public virtual Animal {  public:  virtual void Aletea();  };  // Un murciélago sigue siendo un mamífero con alas  class Murciélago : public Mamífero, public AnimalConAlas {}; 

Ahora la parte Animal de Murciélago::AnimalConAlas es la misma que la usada en Murciélago::Mamífero, que es como decir que un Murciélago solo tiene un Animal en su representación y por tanto llamar a Murciélago::Come() no es ambiguo.

Esto se implementa ofreciendo Mamífero y AnimalConAlas con una vtable ya que, por ejemplo, el desplazamiento de memoria entre el comienzo de un Mamífero y de su parte Animal no se conoce hasta el momento de la ejecución del programa. De esta forma Murciélago pasa a ser (vtable*, Mamífero, vtable*, AnimalConAlas, Murciélago, Animal).

Con dos punteros vtable (vtable*) por objeto, el tamaño del objeto aumenta en dos punteros, pero así solo hay un Animal y no hay ambigüedad. Hay un puntero Animal por cada herencia que hereda virtualmente de Animal: Mamífero y AnimalConAlas. Todos los objetos del tipo Murciélago tendrán los mismos vtable*, pero cada objeto Murciélago contendrá un único objeto Animal propio. Si otra clase hereda de Mamífero, como Ardilla, la vtable* en el objeto Mamífero de Ardilla será diferente del vtable* en el objeto Mamífero de un Murciélago, aunque podrían ser esencialmente el mismo en el caso especial de que la parte Ardilla del objeto tuviera el mismo tamaño que la parte Murciélago, ya que la distancia desde la parte Mamífero hasta la parte Animal sería la misma. Las vtables no son realmente las mismas, pero la información esencial en ellas (la distancia), sí lo es.

  •   Datos: Q1526910

herencia, virtual, herencia, virtual, tipo, herencia, solventa, algunos, problemas, causados, herencia, múltiple, particularmente, problema, diamante, mediante, aclaración, ambigüedad, sobre, qué, miembros, clases, padre, usar, usada, cuando, herencia, está, r. En C herencia virtual es un tipo de herencia que solventa algunos de los problemas causados por la herencia multiple particularmente el problema del diamante mediante la aclaracion de la ambiguedad sobre que miembros de clases padre usar Es usada cuando la herencia esta representando restricciones de un conjunto mas que la composicion de partes Una clase base multi heredada se denota como virtual con la palabra clave virtual El problema EditarConsiderando la siguiente jerarquia de clase class Animal virtual void Come class Mamifero public Animal public virtual Color GetColorPelo class AnimalConAlas public Animal public virtual void Aletea Un murcielago es un mamifero con alas class Murcielago public Mamifero public AnimalConAlas Pero como Come un murcielago Como se ha declarado arriba una llamada a Murcielago Come es ambiguo Deberia llamarse a Murcielago AnimalConAlas Come o a Murcielago Mamifero Come El problema es que la semantica de la herencia multiple convencional no modela la realidad En un sentido un Animal es Animal solo una vez un Murcielago es un Mamifero y un AnimalConAlas pero un Murcielago es tan Animal por ser Mamifero como por ser AnimalConAlas Esta situacion es llamada a veces herencia en diamante y es un problema que la herencia virtual intenta en parte solventar Representacion de clases EditarAntes de seguir es util tener en cuenta como se representan las clases en C Concretamente la herencia es solo cuestion de poner la clase padre y la clase hija una detras de la otra en memoria De esta forma Murcielago es realmente Animal Mamifero Animal AnimalConAlas Murcielago lo que hace que se duplique Animal causando la ambiguedad Solucion EditarPodemos redeclarar nuestras clases de la forma siguiente Dos clases heredando virtualmente de Animal class Mamifero public virtual Animal public virtual Color GetColorPelo class AnimalConAlas public virtual Animal public virtual void Aletea Un murcielago sigue siendo un mamifero con alas class Murcielago public Mamifero public AnimalConAlas Ahora la parte Animal de Murcielago AnimalConAlas es la misma que la usada en Murcielago Mamifero que es como decir que un Murcielago solo tiene un Animal en su representacion y por tanto llamar a Murcielago Come no es ambiguo Esto se implementa ofreciendo Mamifero y AnimalConAlas con una vtable ya que por ejemplo el desplazamiento de memoria entre el comienzo de un Mamifero y de su parte Animal no se conoce hasta el momento de la ejecucion del programa De esta forma Murcielago pasa a ser vtable Mamifero vtable AnimalConAlas Murcielago Animal Con dos punteros vtable vtable por objeto el tamano del objeto aumenta en dos punteros pero asi solo hay un Animal y no hay ambiguedad Hay un puntero Animal por cada herencia que hereda virtualmente de Animal Mamifero y AnimalConAlas Todos los objetos del tipo Murcielago tendran los mismos vtable pero cada objeto Murcielago contendra un unico objeto Animal propio Si otra clase hereda de Mamifero como Ardilla la vtable en el objeto Mamifero de Ardilla sera diferente del vtable en el objeto Mamifero de un Murcielago aunque podrian ser esencialmente el mismo en el caso especial de que la parte Ardilla del objeto tuviera el mismo tamano que la parte Murcielago ya que la distancia desde la parte Mamifero hasta la parte Animal seria la misma Las vtables no son realmente las mismas pero la informacion esencial en ellas la distancia si lo es Datos Q1526910 Obtenido de https es wikipedia org w index php title Herencia virtual amp oldid 125589856, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos