2010-01-28 23 views
15

Es fácil de entender la función virtual en herencia pública. Entonces, ¿cuál es el punto para la función virtual en la herencia privada o protegida?función virtual en herencia privada o protegida

Por ejemplo:

class Base { 
public: 
virtual void f() { cout<<"Base::f()"<<endl;} 
}; 

class Derived: private Base { 
public: 

void f() { cout<<"Derived::f()"<<endl;} 

}; 

¿Sigue siendo llamado primordial? ¿De qué sirve este caso? ¿Cuál es la relación de estos dos f()?

Gracias!

Respuesta

11

herencia privada es sólo una técnica de aplicación, no una relación es-un, como Scott Meyers explica en efectivo de C++:

class Timer { 
public: 
    explicit Timer(int tickFrequency); 
    virtual void onTick() const; // automatically called for each tick 
    ... 
}; 

class Widget: private Timer { 
private: 
    virtual void onTick() const; // look at Widget private data 
    ... 
}; 

clientes Widget no debería ser capaz de llamar a onTick en un Widget, porque eso es no es parte de la interfaz conceptual del widget.

+0

Ese es otro buen ejemplo. – Omnifarious

+0

De hecho, eso es simplemente viejo un buen ejemplo. Respondí la pregunta incorrecta. Oops. :-) – Omnifarious

1
  • No tiene que ser un punto para cada combinación de características diferentes. Simplemente puedes combinarlos.
  • Un miembro protegido virtual es accesible para las clases derivadas, por lo que es útil para ellos.
  • Un miembro privado virtual es accesible para las clases de amigos, por lo que es útil para ellos.
1

Un ejemplo sería:

/// Thread body interface 
class runnable 
{ 
public: 

    virtual ~runnable() {} 
    virtual void run() =0; 
}; 

/// Starts OS thread, calls p->run() in new thread 
thread_id start_thread(runnable* p); 

/// Has a private thread 
class actor: private runnable, private noncopyable 
{ 
private: 

    thread_id tid; /// private thread 

public: 

    actor() { tid = start_thread(this); } // here this IS-A runnable 
    // ... 
    virtual ~actor() { stop_thread(tid); } 

private: 

    virtual void run() { /* work */ } 
}; 
+0

-1: este ejemplo * realmente * necesita mostrar quién llama 'run()' – Potatoswatter

+0

La función start_thread() por supuesto. –

+0

Pero, ¿cómo se llama 'ejecutar'?Es privado. –

1

Tanto la herencia privada y protegida permite funciones virtuales primordiales en la clase de base privada/protegido y ni las reclamaciones de los derivados es un tipo de su base.

La herencia protegida permite que las clases derivadas de clases derivadas conozcan la relación de herencia y aún anulen las funciones virtuales.

heredar privada de la clase Base en su clase Derived, destruye todos los vínculos conceptuales entre la clase derivada y la base. La clase derivada se acaba de implementar en términos de la clase base, nada más. La herencia privada es solo una técnica de implementación y no implica relación entre las clases involucradas.

3

Su método f() sigue anulado. Esta relación es útil cuando se implementa el patrón de diseño Template Method. Básicamente, implementaría conjuntos comunes de operaciones en la clase base. Esas operaciones de clase base invocarían un método virtual, como su f(). Si la clase derivada anula f(), las operaciones de la clase base terminan llamando a la versión derivada de f(). Esto permite que las clases derivadas mantengan el algoritmo base igual, pero modifique el comportamiento para satisfacer sus necesidades. Aquí está un ejemplo trivial:

#include <iostream> 

using namespace std; 

class Base 
{ 
public: 
    virtual void f() { cout<<"Base::f()" << endl; } 
protected: 
    void base_foo() { f(); } 
}; 

class DerivedOne: private Base 
{ 
public: 
    void f() { cout << "Derived::f()" << endl;} 
    void foo() { base_foo(); } 
}; 

class DerivedTwo: private Base 
{ 
public: 
    void foo() { base_foo(); } 
}; 

int main() 
{ 
    DerivedOne d1; 
    d1.foo(); 

    DerivedTwo d2; 
    d2.foo(); 
} 

Aquí está el resultado en tiempo de ejecución:

$ ./a.out 
Derived::f() 
Base::f() 

clases derivadas Tanto llaman la misma operación de clase base, pero el comportamiento es diferente para cada clase derivada.

Cuestiones relacionadas