Sobrescribir el método opaca la versión final sobrecargada.
Tengo el siguiente código:
struct Abs {
virtual void f(int x) = 0;
virtual void f(double x) final { std::cout << 2; }
};
struct Sub: public Abs {
void f(int x) final { std::cout << 1; }
};
Abs
es una clase abstracta que comprende una función miembro pura void f(int)
y su versión sobrecargada void f(double x)
, la cual ya no es pura y está marcada como final
. Si intento anular void f(int)
en la estructura derivada Sub
, esta oscurecerá void f(double)
y la siguiente función main
imprimirá 1
, convirtiendo 1.01
a int
:
int main() {
Sub x = {};
x.f(1.01);
return 0;
}
¿Cómo puedo superar este problema? Además, ¿por qué funciona así?
davy.ai
El problema en este código surge del uso de la palabra clave
final
en la definición devoid f(double x)
en la claseAbs
. Cuando una función miembro en la clase base se declara comofinal
, no puede ser sobrescrita en ninguna de sus clases derivadas. Por lo tanto, cuando intentamos sobrescribirvoid f(int x)
en la clase derivadaSub
, no sobrescribe la funciónfinal
void f(double x)
en la clase base.Para superar este problema, podemos quitar la palabra clave
final
de la definición devoid f(double x)
en la claseAbs
. Esto permitirá que la clase derivadaSub
sobrescriba la funciónvoid f(int x)
sin problemas.El código con la clase
Abs
corregida se vería así:Esto imprimirá
2
en lugar de1
, ya que la funciónvoid f(int x)
sobrescrita en la claseSub
ya no ocultará la funciónvoid f(double x)
en la claseAbs
.En resumen, la palabra clave
final
en la clase base impide que la clase derivada sobrescriba esa función en particular. Al quitar la palabra clavefinal
, se permitirá que la clase derivada lo sobrescriba.