¿Sobrescribir una función virtual pero no una función virtual pura?
Estoy intentando derivar una clase C
de dos clases, A
y B
; después de leer esta respuesta, intenté escribir using B::<función>
para anular una función virtual pura en A
con la implementación en B
.
Sin embargo, el enfoque de esa respuesta no funciona para funciones virtuales puras; en ese caso, descubrí que necesitaba ser más explícito.
Entonces, evidentemente, using
puede resolver la ambigüedad, ¿pero no puede introducir una implementación?
Solo esperaba entender mejor qué está sucediendo aquí.
“` cpp
struct A {
// esto resultaría en ambigüedad:
//virtual void e(void) const {} // ERROR: miembro 'e' encontrado en varias clases base
// resolviendo la ambigüedad con 'using'
virtual void f(void) const {} // OK
// esto resultaría en un método no implementado:
//virtual void g(void) const = 0; // ERROR: el tipo de variable 'C' es una clase abstracta
// *** ¿por qué esto no funciona? ***
//virtual void h(void) const = 0; // ERROR: el tipo de variable 'C' es una clase abstracta
// resolviendo la ambigüedad definiendo explícitamente lo que quiero
virtual void i(void) const = 0; // OK
};
struct B {
void e(void) const {}
void f(void) const {}
void g(void) const {}
void h(void) const {}
void i(void) const {}
};
struct C : public A, public B {
using B::f; // es suficiente para fijar 'f'
using B::h; // no es suficiente para fijar 'h'
void i(void) const { B::i(); } // es suficiente para fijar 'i'
};
int main() {
C X;
X.e();
X.f();
X.g();
X.h();
X.i();
}
“`</función>
davy.ai
La pregunta se refiere al uso de la palabra clave
using
para derivar una claseC
de dos clasesA
yB
, y anular una función virtual pura enA
con la implementación enB
. El enfoque en la respuesta enlazada no funcionó para funciones virtuales puras, y la pregunta solicita una mejor comprensión de lo que está sucediendo.El código proporcionado muestra que
using
puede resolver la ambigüedad, pero no puede introducir una implementación. Esto es evidente por el hecho de que usarB::h
no es suficiente para definirh
y aún así resulta en un método no implementado. Esto se debe a queusing
solo trae nombres de la clase base al ámbito de la clase derivada, pero no afecta a la tabla de funciones virtuales (o vtable) de la clase.Por lo tanto, en el caso de una función virtual pura, la clase derivada
C
debe proporcionar su propia implementación o heredarla de otra clase base. Esto es lo que sucede cuandoC
define explícitamentei
comovirtual void i(void) const = 0;
. Esto es suficiente para definiri
y el programa se compila sin errores.En resumen,
using
puede resolver la ambigüedad, pero no puede introducir una implementación para funciones virtuales puras. Una clase derivada debe proporcionar su propia implementación o heredarla de otra clase base.