Al leer un libro de texto, he tenido la impresión de que anular funciones virtuales solo funciona cuando se usa un puntero o una referencia al objeto. El libro demuestra la creación de un puntero del tipo de clase base que apunta a un objeto del tipo de clase derivado, y lo utiliza para demostrar una anulación de función virtual.
Sin embargo, ahora me he encontrado con lo siguiente. No hay un puntero a la vista, y esperaba que hacer que la función1 sea virtual no haría la diferencia, pero lo hace. Claramente me falta algo aquí y agradecería una explicación de lo que es. Lo siento si mi explicación no es clara; También espero que esto se haya preguntado antes, pero no se me ocurrió qué buscar.
using namespace std;
class ClassA
{
public:
void function1(); // virtual or not?
void function2();
};
class ClassB : public ClassA
{
public:
void function1();
};
int main()
{
ClassA objA;
ClassB objB;
objA.function1();
cout << "\n";
objA.function2();
cout << "\n";
objB.function1();
cout << "\n";
objB.function2(); // Fourth call
cout << "\n";
}
void ClassA::function1() { cout << "ClassA::function1\n"; }
void ClassA::function2()
{
cout << "ClassA::function2\n";
function1(); // For the fourth call ClassA::function1()
// is called if ClassA::function1() is not virtual
// but ClassB:function1() is called if it is. Why?
}
void ClassB::function1() { cout << "ClassB::function1\n"; }
Muchas gracias por cualquier ayuda.
3 respuestas
Ejemplo de virtual sin punteros explícitos:
class A
{
public:
virtual void f1()
{
cout << "A::f1()" << endl;
}
void f2()
{
f1();
}
};
class B : public A
{
public:
void f1() override
{
cout << "B::f1()" << endl;
}
};
int main()
{
A a;
B b;
a.f2();
b.f2();
}
La función1 no es virtual, obj2 llama a la clase1 función1 porque es un objeto clasB, el compilador primero busca el tipo más derivado para una función, luego la base más a la izquierda (y luego a través de las bases de esa base), y luego la siguiente base en múltiples situaciones de herencia. Si tomó una clase A * para obj2 y llamó a la función1, llamaría a la clase1 función1.
No es una función virtual ya que no está marcada como una. Es simplemente una función pública accesible desde una clase / objeto derivado. Su código tampoco exhibe un comportamiento polimórfico. Dicho esto, ninguna de sus funciones es virtual ni anulación. Un ejemplo trivial para la instalación polimórfica sería:
#include <iostream>
#include <memory>
class ClassA {
public:
virtual void function1() { // now virtual
std::cout << "ClassA::function1\n";
}
};
class ClassB : public ClassA {
public:
void function1() override {
std::cout << "ClassB::function1\n";
}
};
int main() {
std::unique_ptr<ClassA> p = std::make_unique<ClassB>();
p->function1(); // now calls class B function, overrides class A behavior
}
O a través de referencias:
int main() {
ClassB objB;
ClassA& ro = objB;
ro.function1(); // now calls class B function, overrides class A behavior
}
Hay pocos beneficios en las funciones de marcado como virtual
y override
si no está utilizando el comportamiento polimórfico.
Preguntas relacionadas
Nuevas preguntas
c++
C ++ es un lenguaje de programación de propósito general. Originalmente fue diseñado como una extensión de C, y tiene una sintaxis similar, pero ahora es un lenguaje completamente diferente. Use esta etiqueta para preguntas sobre el código (que se compilará) con un compilador de C ++. Utilice una etiqueta específica de la versión para preguntas relacionadas con una revisión estándar específica [C ++ 11], [C ++ 14], [C ++ 17] o [C ++ 20] etc.