Pregunta

Yo sólo vi esto en algún código:

class Foo {
[...]
private:
    virtual void Bar() = 0;
[...]
}

¿Tiene esto algún propósito?

(Estoy tratando de puerto de un cierto código de VS y G ++, y esto me llamó la atención)

¿Fue útil?

Solución

esta hierba Sutter artículo cuanto a por qué te gustaría hacer tal cosa.

Otros consejos

Esta es una función virtual pura que pasa a ser privado. Esto hace que para que una clase derivada debe implementar el método. En este caso bar.

Creo que puede ser confundida b / c esto se hace para crear "interfaces" en C ++ y muchas veces la gente piensa de ellos como públicos. Hay casos en que es posible que desee definir una interfaz que es privado, donde un método público utiliza los métodos privados con el fin de garantizar el orden de cómo se llaman. (Creo que esto se llama el Método plantilla)

En un tiempo relativamente mal ejemplo :)

class RecordFile
{
    public:
       RecordFile(const std::string &filename);

       void process(const Record &rec)
       {
           // Call the derived class function to filter out
           // records the derived instance of this class does
           // not care about
           if (filterRecord(rec))    
           {
               writeRecordToFile(rec);           
           }
       };

    private:
       // Returns true if the record is of importance
       // and should be kept
       virtual bool filterRecord(const Record &rec) = 0;

       void writeRecordToFile(const Record &rec);
};

ISO C ++ 2003 permite explícitamente:

§ 10.3 establece nada sobre especificador de acceso y contiene incluso una nota al pie en la segunda cláusula que establece en el contexto de las anulaciones de funciones virtuales:

  

[...] El control de acceso (cláusula 11) es   no se considera en la determinación   primordial.

El código es totalmente legal.

La respuesta habitual "académica" es:. Especificadores de acceso y virtualidad son ortogonales - una no afecta a la otra

Un poco de respuesta más práctica: funciones virtuales privadas a menudo se utilizan para implementar el patrón de diseño de la plantilla Método . En lenguajes que no soportan las funciones virtuales privadas, el método de la plantilla tiene que ser pública aunque no sirve realmente para ser una parte de la interfaz.

Me voy a citar una breve explicación de la gran C ++ FAQ Lite que resume bien:

  

[23.4] Cuando alguien debería usar privada   virtuals?

     

Casi nunca.

     

virtuals protegidas están bien, pero   los virtuales privadas son por lo general una red de   pérdida. Motivo: los virtuales privadas confunden   nueva C ++ programadores, y confusión   Los aumentos de costos, retrasos en el programa, y   degrada riesgo.

     

Nueva programadores de C ++ se confunden con   los virtuales privadas porque piensan que una   privada virtual no puede ser cambiada.   Después de todo, una clase derivada no puede   miembros de acceso que son privadas en su   clase base para qué, se preguntan, ¿verdad   anular una privada virtual de su   clase base? Hay explicaciones para   lo anterior, pero eso es académico. los   verdadero problema es que casi todo el mundo   se confunde la primera vez que se ejecutan   en los virtuales privadas, y la confusión   es malo.

     

A menos que haya una razón de peso para   Al contrario, evitar los virtuales privadas.


El C ++ FAQ Lite fue actualizado en el ínterin:

  

Por cierto, confunde la mayoría de los programadores novatos ++ C que los virtuales privadas puede ser anulado, y menos aún son válidos en absoluto. A todos nos han enseñado que los miembros privados de una clase base no son accesibles en las clases derivadas de ella, lo cual es correcto. Sin embargo, esta falta de acceso por la clase derivada no tiene nada que ver con el mecanismo de llamada virtual, que es a la clase derivada. Ya que ello podría confundir a los principiantes, C ++ FAQ anteriormente recomienda el uso de los virtuales protegidas en lugar de los virtuales privadas. Sin embargo, el enfoque privada virtual es ahora bastante común que la confusión de los novatos es una preocupación menor.

Es una función virtual pura. Cualquier aplicación final que se deriva de "alimento" debe implementar la función "bar".

Esto hace que la función virtual pura en contraposición a lo virtual.

No se proporciona la aplicación por defecto y la intención es que la implementación de la función debe ser especificado por una clase que hereda. Esto puede ser anulado sin embargo.

A veces se ve clases completas, donde todas las funciones miembro se especifican como virtual pura de esta manera.

Estas son las clases base abstractas, a veces se hace referencia como clases de interfaz, y el diseñador de la ABC es que te dice: "Tengo ahora idea de cómo se llevaría a cabo esta funcionalidad para todas las especialidades de esta clase base. Sin embargo, se debe tienen todos ellos definidos para su especialización para trabajar y usted sabe cómo su objeto debe comportarse".

Editar Vaya, sólo vio el hecho de que la función virtual pura es miembro privado. (Gracias Michael) Esto cambia un poco las cosas.

Cuando esta clase base es heredada utilizando la herencia privada que cambia las cosas. Básicamente lo que el diseñador de la clase base está haciendo es diciendo es que, cuando su clase derivada llama a una función no privada en la clase base. parte del comportamiento ha sido delegada a su especialización de la función en la clase derivada. El miembro no privado está haciendo "algo" y parte de ese "algo" es un llamado, a través de la función virtual pura clase base, a su aplicación.

Así que alguna función pública en Foo está llamando a la función de la barra en el interior de Foo, y se basa en el hecho de que va a proporcionar una aplicación especializada de la función de la barra para su caso particular.

Scott Meyers refiere a esto como "implementado en términos de".

Por cierto Sólo riendo sobre el número de respuestas que se han eliminado rápidamente por personas que tampoco vio la "letra" en la pregunta! (-:

HTH

aplausos,

El único propósito que parece servir es proporcionar una interfaz común.

Por cierto a pesar de que una función se declara como privada virtual, todavía puede ser implementado y llamó a la instancia de la clase o de amigos.

Sin embargo, este tipo de cosas por lo general destinado a servir como interfaz, sin embargo, no lo hacen de esta manera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top