c++ - sobreescribir - ¿Hay alguna diferencia entre una función virtual pura privada y protegida?
sobreescribir metodo c++ (2)
Puedo entender que puede haber una razón para declarar que una función virtual implementada (en lugar de pura) es privada o está protegida. Afaik, si declara que un método virtual implementado está protegido, su clase secundaria puede llamar al método de la clase base (y nadie más puede hacerlo). Si lo declara privado, solo la clase base puede llamar a la implementación predeterminada del método virtual.
Sin embargo, con los virtuales puros, no hay una implementación básica ... ¿Entonces no es funcionalmente equivalente declarar un virtual puro como privado o protegido? Un virtual puro protegido no tiene sentido porque nunca se puede invocar el método correspondiente de la clase base. ¿Hay algún escenario donde un virtual puro protegido tenga algún sentido?
Hay algunos temas similares en SO, pero no pude encontrar nada que respondiera de manera concisa a mi pregunta.
¿Hay algún escenario donde un virtual puro protegido tenga algún sentido?
Creo que te refieres a privado aquí (en lugar de protegido), pero creo que entiendo tu punto. De hecho, el tipo de acceso de un virtual puro puede ser anulado en clases derivadas. Este es un ejemplo que podría ayudarlo a ver la diferencia entre un virtual puro protegido y uno privado:
class Parent
{
protected: virtual void foo() = 0;
private: virtual void bar() = 0;
public: void test() { foo(); bar(); }
};
class Child : public Parent
{
public: void test2() { foo(); /* bar(); // cannot be called here */ }
};
class GrandChild : public Child
{
// access types here can be anything for this example
public: void foo() { cout << "foo" << endl; }
public: void bar() { cout << "bar" << endl; }
};
Primera función virtual pura puede ser implementada!
#include <iostream>
class Animal
{
public:
void eat(void);
protected:
virtual void doEat(void)=0;
};
void Animal::eat(void)
{
doEat();
}
void Animal::doEat(void)
{
std::cout << "animal" << std::endl;
}
class Tiger : public Animal
{
private:
virtual void doEat(void)
{
Animal::doEat();//here is the difference between protected and private
std::cout << "tiger" << std::endl;
}
};
int main(void)
{
Animal *p = new Tiger();
p->eat();
return 0;
}
En segundo lugar, Herb Sutter explicó cuándo usar "virtual privado" o "virtual protegido", puede leer este article . Creo que esto explica por qué hacemos esto, no solo podemos. El artículo dice: "Prefiero que las funciones virtuales sean privadas. Solo si las clases derivadas necesitan invocar la implementación básica de una función virtual, hacer que la función virtual esté protegida ", su pregunta es acerca de la función virtual pura, no estoy muy seguro de si satisface este principio.