2010-07-22 14 views
5

¿Por qué querría definir una interfaz C++ que contenga métodos privados?Método privado en una interfaz C++?

Incluso en el caso en que los métodos en el ámbito público técnicamente supongan que actúan como métodos de plantilla que utilizan los métodos privados en la implementación de la interfaz, aún así, estamos diciendo las especificaciones técnicas. directamente desde la interfaz.

¿No es esto una desviación del uso original de una interfaz, es decir, un contrato público entre el exterior y el interior?

También podría definir una clase de amigo, que hará uso de algunos métodos privados de nuestra clase, y así forzar la implementación a través de la interfaz. Esto podría ser un argumento.

¿Qué otros argumentos son para definir un método privado dentro de una interfaz en C++?

+1

interfaz! = Miembros públicos. Su interfaz es su _documentation_, no su archivo de encabezado. –

Respuesta

6

La vista OO común es que una interfaz establece un contrato único que define cómo se utilizan los objetos que se ajustan a esa interfaz y cómo se comportan. El idioma NVI o patrón, que nunca se sabe cuando uno se convierte en el otro, se propone un cambio en la mentalidad de dividir la interfaz en dos contratos separados:

  • forma en que la interfaz es para usarse
  • lo que las clases derivadas deben ofrecer

Esto es, en cierto sentido particular a C++ (de hecho a cualquier idioma con la herencia múltiple), donde la interfaz de puede de hecho contener código que se adapta a la interfaz externa --¿Cómo usuarios ven me-- y la interfaz interna - cómo estoy implementado.

Esto puede ser útil en casos diferentes, primero cuando el comportamiento es común pero se puede parametrizar solo de manera específica, con un esqueleto de algoritmo común. Entonces el algoritmo puede implementarse en la clase base y los puntos de extensión en los elementos derivados. En idiomas sin herencia múltiple, esto debe implementarse dividiéndolo en una clase que implemente el algoritmo basado en algunos parámetros que cumplan con una interfaz 'privada' diferente. Estoy usando aquí 'privado' en el sentido de que solo tu clase usará esa interfaz.

El segundo uso común es que mediante el uso del idioma NVI, es simple para instrumentar el código sólo por la modificación en el nivel de base:

class Base { 
public: 
    void foo() { 
     foo_impl(); 
    } 
private: 
    virtual void foo_impl() = 0; 
}; 

El coste adicional de tener que escribir el despachador foo() { foo_impl(); } es bastante pequeño y le permite agregar más adelante un mecanismo de bloqueo si convierte el código en una aplicación multiproceso, agrega el registro a cada llamada, o un temporizador para verificar cuánto implementaciones diferentes toman en cada función ... Dado que el método real que se implementa en las clases derivadas es privado en este nivel, se le garantiza que todas las llamadas polimórficas se pueden instrumentar en un único punto: la base (esto no bloquea la extensión de clases desde haciendo foo_impl pensamiento pública)

void Base::foo() { 
    scoped_log log("calling foo"); // we can add traces 
    lock l(mutex);     // thread safety 
    foo_impl(); 
} 

Si los métodos virtuales fueron públicas, entonces no podría interceptar todas las llamadas a los métodos y tendría que agregar que la tala y el hilo de seguridad para todos las clases derivadas que implementan la interfaz .

3

Puede declarar un método virtual privado cuyo propósito se derivará. Ejemplo:

class CharacterDrawer { 
public: 
    virtual ~CharacterDrawer() = 0; 

    // draws the character after calling getPosition(), getAnimation(), etc. 
    void draw(GraphicsContext&); 

    // other methods 
    void setLightPosition(const Vector&); 

    enum Animation { 
     ... 
    }; 

private: 
    virtual Vector getPosition() = 0; 
    virtual Quaternion getRotation() = 0; 
    virtual Animation getAnimation() = 0; 
    virtual float getAnimationPercent() = 0; 
}; 

Este objeto puede proporcionar dibujo utilidad para un carácter, sino que tiene que ser derivated por un objeto que proporciona movimiento, manipulación de animación, etc.

La ventaja de hacerlo como este en lugar de provinding " setPosition "," setAnimation ", etc. es que no tiene que" presionar "el valor en cada fotograma, sino que lo" jala ".

Creo que esto se puede considerar como una interfaz, ya que estos métodos no tienen nada que ver con la implementación real de todo el material relacionado con el dibujo.

0

En una implementación de método de plantilla, se puede usar para agregar una restricción de especialización: no se puede invocar el método virtual de la clase base de la clase derivada (de lo contrario, el método se declarará como protegido en la clase base):

class Base 
{ 
private: 
    virtual void V() { /*some logic here, not accessible directly from Derived*/} 
}; 

class Derived: public Base 
{ 
private: 
    virtual void V() 
    { 
     Base::V(); // Not allowed: Base::V is not visible from Derived 
    } 
}; 
3

¿Por qué querría para definir una interfaz de C++ que contiene métodos privados?

La pregunta es un poco ambigua/contradictorios: si se define (meramente) una interfaz, eso significa que se define el pública el acceso de cualquier cosa que se conecta a él. En ese sentido, no define una interfaz que contenga métodos privados.

Creo que su pregunta proviene de confundir una clase base abstracta con una interfaz (corríjanme si me equivoco).

Una clase base abstracta puede ser una implementación de funcionalidad parcial (o incluso completa), que tiene al menos un miembro abstracto. En este caso, tiene tanto sentido tener miembros privados como lo hace para cualquier otra clase.

En la práctica, rara vez es necesario tener clases básicas virtuales puras sin implementación (es decir, clases base que solo definen una lista de funciones virtuales puras y nada más). Un caso donde se requiere es la programación COM/DCOM/XPCOM (y hay otros). En la mayoría de los casos, aunque tiene sentido agregar alguna implementación privada a su clase base abstracta.

Cuestiones relacionadas