C ++ de programación: cuando es una función virtual no?
En C ++, sólo porque usted piensa que una llamada de función en particular está obligado tarde no significa que lo sea. Si no declarado con los mismos argumentos en las subclases, las funciones miembro no se redefinen polimórficamente, sean o no se declaran virtual.
Una excepción a la regla de la declaración idéntica es que si la función de miembro en la clase base devuelve un puntero o referencia a un objeto de clase base, una función miembro reemplaza en una subclase puede devolver un puntero o referencia a un objeto de la subclase. En otras palabras, la función de Hacer una copia() es polimórfico, a pesar de que el tipo de retorno de las dos funciones difieren:
Clase base {public: // devuelve una copia de la corriente objectBase * makeACopy () -} - Clase Subclase: Base pública {public: // devuelve una copia de la corriente objectSubClass * makeACopy () -} - void fn (Base bc) {Base * PCOPY = bc.makeACopy () - // proceder sobre ...}
En la práctica, esto es bastante natural. LA Hacer una copia() función debe devolver un objeto de tipo Subclase, a pesar de que podría anular BaseClass :: makeACopy ().
Este asunto de silencio decidir cuando una función se anula y cuando no es una fuente de error en C ++ - tanto es así que el estándar de 2011 introdujo el descriptor anular que el programador puede utilizar para indicar su intención de anular una función de clase base.
C ++ genera un error del compilador si una función se declara anulación, pero no es así, de hecho, anula una función de clase base por alguna razón (como un argumento mal) como en el siguiente ejemplo:
clase Student {public: virtual void addCourseGrade (doble grado) -} - clase GradStudent: Estudiante pública {public: addCourseGrade (grado float) override void virtuales -} -
Este fragmento de código genera un error en tiempo de compilación porque el método GradStudent :: addCourseGrade (float) fue declarado anular pero no, de hecho, reemplazar la función de la clase base Estudiante :: addCourseGrade (doble) debido a que los tipos de argumentos no coinciden.
El programador también puede declarar una función que no overrideable utilizando el final palabras clave, incluso si esa función en sí anula alguna función de la clase base anterior, como se demuestra en el siguiente adicional PostDoc clase:
clase GradStudent: Estudiante pública {public: virtual void addCourseGrade (doble grado) final -} - clase PostDoc: GradStudent pública {public: virtual void addCourseGrade (doble grado) -} -
Desde Estudiante :: addCourseGrade () está marcado final, la declaración de PostDoc :: addCourseGrade () genera un error porque intenta anular el Estudiante método.
Además, toda una clase puede ser declarada definitiva:
GradStudent clase final: Estudiante pública
Esto afecta a algo más que los métodos virtuales de la clase. LA final clase no se puede heredar de nada.