¿Por qué una función virtual sería privada?


Acabo de ver esto en algún código:

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

¿Tiene esto algún propósito?

(Estoy tratando de portar algún código de VS a G++, y esto me llamó la atención)

Author: curiousguy, 2009-07-16

8 answers

Vea este artículo de Herb Sutter en cuanto a por qué querría hacer tal cosa.

 22
Author: Greg Rogers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-15 20:55:37

Esta es una función virtual pura que resulta ser privada. Esto hace que una clase derivada deba implementar el método. En este caso Bar.

Creo que puede estar confundido b/c esto se hace para crear "interfaces" en C++ y muchas veces la gente piensa que son públicas. Hay casos en los que puede querer definir una interfaz que es privada donde un método público utiliza esos métodos privados para garantizar el orden de cómo se llaman. (Creo que esto se llama el Método de la plantilla)

Para un ejemplo relativamente malo:)

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);
};

 10
Author: RC.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-15 21:59:07

ISO C++ 2003 lo permite explícitamente:

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

[...] Access control (clause 11) is no considerado en la determinación primordial.

El código es totalmente legal.

 9
Author: ovanes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-30 18:24:37

La respuesta "académica" habitual es: los especificadores de acceso y la virtualidad son ortogonales - uno no afecta al otro.

Una respuesta un poco más práctica: las funciones virtuales privadas se utilizan a menudo para implementar el método de plantilla patrón de diseño. En lenguajes que no admiten funciones virtuales privadas, el método de plantilla debe ser público, aunque en realidad no está destinado a ser parte de la interfaz.

 5
Author: Nemanja Trifunovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-15 21:12:07

Voy a citar una breve explicación de la gran C++ FAQ Lite {[2] } que lo resume bien:

[23.4] ¿Cuándo debe alguien usar privado virtuals?

Casi nunca.

Virtuals protegidos están bien, pero los virtuals privados son generalmente una red perdida. Motivo: las virtualidades privadas confunden nuevos programadores de C++ y confusión aumenta el costo, retrasa el cronograma y degrada el riesgo.

Los nuevos programadores de C++ se confunden por virtuals privados porque piensan que un privado virtual no puede ser anulado. Después de todo, una clase derivada no puede acceder a los miembros que son privados en su clase base, entonces, ¿cómo, se preguntan, podría anular un virtual privado desde su clase base? Hay explicaciones para lo anterior, pero eso es académico. El el problema real es que casi todos se confunde la primera vez que corren en virtualidades privadas, y confusión es malo.

A menos que haya una razón convincente para por el contrario, evitar virtuales privados.


El C++ FAQ Lite se actualizó mientras tanto:

Por cierto, confunde a la mayoría de los programadores novatos de C++ que los virtuales privados pueden ser anulados, y mucho menos son válidos. A todos nos enseñaron que los miembros privados de una clase base no son accesibles en las clases derivadas de ella, lo cual es correcto. Sin embargo, esta inaccesibilidad por parte de la clase derivada no tiene nada que ver con el mecanismo de llamada virtual, que es a la clase derivada. Ya eso podría confundir a los novatos, las preguntas frecuentes de C++ anteriormente recomendaban usar virtuales protegidos en lugar de virtuales privados. Sin embargo, el enfoque virtual privado ahora es lo suficientemente común como para que la confusión de los novatos sea menos preocupante.

 5
Author: Idan K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-02 13:41:14

Es una función virtual pura. Cualquier implementación final que se dervied desde " Foo "DEBE implementar la función" Bar".

 2
Author: Goz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-15 20:52:06

Hace que la función sea pura virtual en lugar de virtual.

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

A veces se ven clases completas donde todas las funciones miembro se especifican como virtuales puras de esta manera.

Estas son Clases Base Abstractas, a veces denominadas Clases de Interfaz, y el diseñador del ABC les está diciendo: "Yo ahora tenga idea de cómo se implementaría esta funcionalidad para todas las especializaciones de esta clase base. Pero, debes tener todo esto definido para que tu especialización funcione y sabes cómo debe comportarse tu objeto".

Editar: Oops, acabo de ver el hecho de que la función virtual member pure es privada. (Gracias Michael) Esto cambia las cosas ligeramente.

Cuando esta clase base se hereda usando herencia privada cambia las cosas. Básicamente lo que el diseñador de la la clase base está haciendo es decir es que, cuando su clase derivada llama a una función no privada en la clase base. parte del comportamiento se ha delegado a su especialización de la función en su clase derivada. El miembro no privado está haciendo " algo "y parte de ese" algo " es una llamada, a través de la función de clase base virtual pura, a su implementación.

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

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

Por cierto, simplemente riéndose sobre el número de respuestas que fueron rápidamente eliminadas por personas que tampoco vieron la "letra pequeña" en la pregunta! (-:

HTH

Salud,

 1
Author: Rob Wells,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-15 21:13:39

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

Por cierto, aunque una función se declara como virtual privada, todavía se puede implementar y llamar con la instancia de la clase o desde amigos.

Sin embargo, este tipo de cosas generalmente tienen la intención de servir como interfaz, sin embargo, no lo hago de esta manera.

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-15 20:57:25