tutorial programas parametros hacer funciones ejemplos con completo como comandos codigos c++ function polymorphism override

programas - manual completo de c++ pdf



AnulaciĆ³n de la funciĆ³n de C++ (6)

Tengo tres clases básicas diferentes:

class BaseA { public: virtual int foo() = 0; }; class BaseB { public: virtual int foo() { return 42; } }; class BaseC { public: int foo() { return 42; } };

Luego derivo de la base como esta (sustituyo X por A, B o C):

class Child : public BaseX { public: int foo() { return 42; } };

¿Cómo se invalida la función en las tres clases base diferentes? ¿Son correctos mis tres supuestos siguientes? ¿Hay otras advertencias?

  • Con BaseA, la clase secundaria no se compila, la función virtual pura no está definida.
  • Con BaseB, se llama a la función en el niño cuando se llama a foo en un BaseB * o Niño *.
  • Con BaseC, la función en el elemento secundario se llama cuando se llama a foo en Child * pero no en BaseB * (se llama a la función en la clase padre).

Con BaseA, la clase secundaria no se compila, la función virtual pura no está definida

Esto es cierto solo si intentas crear un objeto de BaseA. Si creas un objeto de Child y luego puedes llamar a foo () usando BaseA * o Child *

Con BaseB, se llama a la función en el niño cuando se llama a foo en un BaseB * o Niño *.

Depende del tipo de objeto, ya que el objeto puede ser BaseB o Child. Si el objeto es BaseB, se llama a BaseB :: foo.

Con BaseC, se llama a la función en el hijo cuando se llama a foo en Child * pero no en BaseB * (se llama a la función en la clase padre).

Sí, pero nunca quieres hacer esto.


Class Child compilará si se deriva de A, simplemente no puede instanciar objetos de ese tipo.

Esto podría ser valioso si fuera a anular algunas funciones de Base y luego derivar nuevamente.


Depende principalmente de cómo lo llamaste.

si lo hiciste:

class Child : public BaseA { public: int foo() { return 42; } };

y lo hizo

BaseA baseA = new Child(); baseA->foo();

Llamaría a la función foo de Child.

Sin embargo, si hiciste esto:

BaseA baseA = new BaseA();

Produciría un error de tiempo de compilación.


Desde el punto de vista del polimorfismo, prefiera A, para que sepa que cada niño tiene su propia implementación de la función virtual.
Elija B principalmente si tiene una implementación predeterminada válida, pero luego debe asegurarse de que todas las clases secundarias tengan su propia implementación según sea necesario. C no es polimorfismo, así que úsalo juiciosamente.


En la clase derivada, un método es virtual si está definido como virtual en la clase base, incluso si la palabra clave virtual no se usa en el método de la clase derivada.

  • Con BaseA , se compilará y ejecutará según lo previsto, con foo() siendo virtual y ejecutándose en la clase Child .
  • Lo mismo con BaseB , también se compilará y ejecutará según lo previsto, con foo() siendo virtual () y ejecutándose en la clase Child .
  • Sin embargo, con BaseC , se compilará y ejecutará, pero ejecutará la versión de BaseC si la llama desde el contexto de BaseC , y la versión de Child si llama con el contexto de Child .

La regla importante a recordar es que una vez que una función se declara virtual, las funciones con firmas coincidentes en las clases derivadas son siempre virtuales. Por lo tanto, está anulado para Child of A y Child of B, que se comportaría de forma idéntica (con la excepción de que no puede instanciar directamente BaseA).

Sin embargo, con C, la función no se invalida, sino que se sobrecarga. En esa situación, solo importa el tipo estático: lo llamará sobre lo que es un puntero a (el tipo estático) en lugar de a lo que realmente es el objeto (el tipo dinámico)