virtuales que puro puras polimorfismo objeto modificador herencia funciones c++ private virtual-functions access-specifier function-overriding

c++ - que - ¿Por qué una función virtual sería privada?



polimorfismo puro c++ (8)

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

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

¿Esto tiene algún propósito?

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


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 virtual privada, aún se puede implementar y llamar con la instancia de la clase o desde amigos.

No obstante, este tipo de cosas normalmente sirven como interfaz, pero no lo hago de esta manera.


Es una función virtual pura. Cualquier implementación final que se desvíe de "Foo" DEBE implementar la función "Barra".


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

Creo que puede estar confundido porque esto se hace para crear "interfaces" en C ++ y muchas veces las personas piensan que son públicas. Hay casos en los que es posible que desee definir una interfaz que sea privada en la que 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 plantilla)

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


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

De forma predeterminada, no se proporciona ninguna implementación y la intención es que la implementación de la función debe ser especificada por una clase hereditaria. Esto puede ser anulado sin embargo.

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

Estas son clases base abstractas, a veces denominadas clases de interfaz, y el diseñador de ABC le está diciendo: "Ahora tengo una idea de cómo se implementaría esta funcionalidad para todas las especializaciones de esta clase base. Sin embargo, debe tener todas Estas se definen para que su especialización funcione y usted sabe cómo debe comportarse su objeto ".

Edición: Vaya, acabo de detectar el hecho de que la función virtual pura del miembro es privada. (Gracias Michael) Esto cambia las cosas ligeramente.

Cuando esta clase base se hereda utilizando herencia privada, cambia las cosas. Básicamente, lo que el diseñador de la clase base está haciendo es decir que, cuando la 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.

Entonces, alguna función pública en Foo está llamando a la función de barra 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, solo ríete de la cantidad de respuestas que fueron eliminadas rápidamente por personas que tampoco vieron la "letra pequeña" en la pregunta. (-:

HTH

aclamaciones,


ISO C ++ 2003 lo permite explícitamente:

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

[...] El control de acceso (cláusula 11) no se considera para determinar la anulación.

El código es totalmente legal.


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 a menudo se usan para implementar el patrón de diseño del Método de plantilla . En los idiomas que no admiten funciones virtuales privadas, el método de plantilla debe ser público, aunque en realidad no debe formar parte de la interfaz.



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

[23.4] ¿Cuándo debería alguien usar virtuales privados?

Casi nunca.

Los virtuales protegidos están bien, pero los virtuales privados suelen ser una pérdida neta. Motivo: los virtuales privados confunden a los nuevos programadores de C ++, y la confusión aumenta el costo, retrasa la programación y degrada el riesgo.

Los nuevos programadores de C ++ se confunden con los virtuales privados porque piensan que un virtual privado no puede ser anulado. Después de todo, una clase derivada no puede acceder a los miembros que son privados en su clase base, así que, ¿cómo pueden preguntar si podría anular un virtual privado de su clase base? Hay explicaciones para lo anterior, pero eso es académico. El problema real es que casi todos se confunden la primera vez que se ejecutan en virtuales virtuales y la confusión es mala.

A menos que haya una razón convincente para lo contrario, evite los virtuales privados.

El C ++ FAQ Lite fue actualizado mientras tanto:

Por cierto, confunde a la mayoría de los programadores principiantes de C ++ que los virtuales privados pueden ser anulados, y mucho menos son válidos en absoluto. A todos nos enseñaron que los miembros privados en 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 para la clase derivada. Dado que eso podría confundir a los principiantes, las preguntas frecuentes de C ++ recomendaban el uso de 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 una preocupación menor.