2012-03-19 9 views
16

Entiendo que puede haber una razón para declarar privada o protegida una función virtual implementada (en lugar de pura). Afaik, si declaras que un método virtual implementado está protegido, tu clase hija puede llamar al método de la clase base (y nadie más puede hacerlo). Si declara que es privado, entonces solo la clase base puede invocar la implementación predeterminada del método virtual.¿Hay alguna diferencia entre una función virtual pura privada y protegida?

Sin embargo, con los virtuales puros, no hay una implementación base ... ¿No es funcionalmente equivalente declarar un virtual puro como privado o como 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 una virtual pura protegida tiene algún sentido?

Hay algunos temas similares en SO, pero no pude encontrar nada que respondiera de forma concisa a mi pregunta.

+0

Puede implementar 'friend' para las interfaces. – Matthew

+6

El método virtual puro puede tener cuerpo y se puede invocar explícitamente como base :: foo(). – iammilind

Respuesta

8

¿Hay algún escenario donde un virtual puro protegido hace que sentido?

Creo que quieres decir privado aquí (en lugar de protegido), pero creo que entiendo tu punto. De hecho, el tipo de acceso de un virtual puro puede anularse en las clases derivadas. He aquí un ejemplo que podría ayudarle a ver la diferencia entre una empresa privada y protegida virtual pura:

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; } 
}; 
+0

Gracias por el ejemplo. Solo para aclarar: un virtual privado puro nunca puede ser llamado por ninguno de sus descendientes (pero puede ser implementado por ellos, entonces la clase base puede invocar el método de su descendiente?) – Prismatic

+0

No. En este ejemplo, si GrandChild llamó 'foo () 'dentro de otro de sus métodos, se compilaría y funcionaría como se esperaba, se llamaría 'GrandChild :: foo'. – mfontanini

+2

Sí Pris, una función virtual puede anularse con un tipo de acceso diferente que puede abrir su accesibilidad. – LiquidAsh

4

Primera función virtual pura se puede implementar!

#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 explica cuándo usar "virtual privada" o "virtual protegida", se puede leer en este article .I que esto explica por qué hacemos esto no sólo podemos El artículo dice:" Prefiere hacer que las funciones virtuales sean privadas, solo si las clases derivadas necesitan invocar la implementación base de una función virtual, proteger la función virtual ", su pregunta es acerca de la función virtual pura, no estoy seguro si satisface este principio.

Cuestiones relacionadas