Cuando declaro una clase base, ¿debo declarar todas las funciones en él como virtuales, o debería tener un conjunto de funciones virtuales y un conjunto de funciones no virtuales que estoy seguro no van a heredar?¿Debo declarar todas las funciones virtuales en una clase base?
Respuesta
Una función solo necesita ser virtual si una clase derivada implementará esa función de una manera diferente.
Por ejemplo:
class Base {
public:
void setI (int i) // No need for it to be virtual
{
m_i = i;
}
virtual ~Base() {} // Almost always a good idea
virtual bool isDerived1() // Is overridden - so make it virtual
{
return false;
}
private:
int m_i;
};
class Derived1 : public Base {
public:
virtual ~Derived() {}
virtual bool isDerived1() // Is overridden - so make it virtual
{
return true;
}
};
Como resultado de ello, me gustaría error del lado de no tener nada virtuales a menos que sepa de antemano que tiene la intención de anularlo o hasta que se descubre que necesita el comportamiento. La única excepción a esto es el destructor, para el cual es casi siempre el caso que desea que sea virtual en una clase base.
Las funciones de interfaz deben ser, en general, virtuales. Las funciones que proporcionan funcionalidad fija no deberían.
Tiendo a hacer que solo las cosas que deseo sean anulables sean virtuales. Si mis suposiciones iniciales sobre lo que deseo anular resultan incorrectas, retrocedo y cambio la clase base.
Ah, y obviamente siempre haga que su destructor sea virtual si está trabajando en algo de lo que se heredará.
¿Por qué declarar algo virtual hasta que realmente lo está anulando? Creo que no se trata de estar seguro o no. Siga los hechos: ¿está anulado en alguna parte? ¿No? Entonces no debe ser virtual.
Esto da como resultado una situación en la que si desea cambiar una subclase (para anular un método previamente no anulado), debe cambiar la clase base (para hacer que el método sea virtual), lo que significa que debe recompilar todos los códigos la clase base. En algunos proyectos, la fragilidad de la clase base no es un problema, pero en otros sí lo es. Depende de su proceso de compilación y de si ha publicado la interfaz de la clase base. –
Por lo tanto, los métodos IMO deben ser virtuales si se permite que las subclases los anulen (y se admite el polimorfismo en tiempo de ejecución), y no si realmente lo hacen. –
Si va a crear una clase base (que está seguro de que alguien se deriva de la clase), entonces usted puede hacer las cosas siguientes:
- Hacer destructor virtual (una necesidad para la clase base)
- Definir métodos que debe ser derivado y hacerlos virtuales.
- Defina métodos que no necesitan ser (o no deberían ser) derivados como no virtuales.
- Si las funciones son solo para la clase derivada y no para la clase base, marque como protegidas.
El compilador no sabría qué parte real de código se ejecutará cuando el puntero de tipo base llame a una función virtual. por lo tanto, la pieza real de código que se ejecutará debe evaluarse en tiempo de ejecución de acuerdo con el objeto apuntado por el puntero de la clase base. Por lo tanto, evite el uso de la función virtual si la función no debe ser anulada en una clase heredada.
Versión TLDR: "debe tener un conjunto de funciones virtuales y un conjunto de funciones no virtuales de las que está seguro no van a heredarse". Porque las funciones virtuales provocan una disminución del rendimiento en el tiempo de ejecución.
Solo debe hacer que las funciones que pretende y diseñar sean reemplazadas de forma virtual. Hacer un método virtual no es gratuito en términos de mantenimiento y rendimiento (el mantenimiento es el problema mucho más grande en mi humilde opinión).
Una vez que un método es virtual, se vuelve más difícil razonar sobre cualquier código que use este método.Porque en lugar de considerar lo que haría una llamada a un método, debe considerar lo que las llamadas a los métodos N harían en ese escenario. N representa el número de sub clases que anulan ese método.
La única excepción a esta regla son los destructores. Deben ser virtuales en cualquier clase de la que se pretenda derivar. Es la única manera de garantizar que se llame al destructor apropiado durante la desasignación.
El idioma de interfaz no virtual (C++ Coding Standards elemento 39) dice que una clase base debe tener métodos de interfaz no virtuales, permitiendo que la clase base garantice invariantes y métodos virtuales no públicos para la personalización de la clase base comportamiento por clases derivadas. Los métodos de interfaz no virtual llaman a los métodos virtuales para proporcionar el comportamiento sobresatible.
Considera agregar la fuente aquí. Encontrado se refiere a "Estándares de codificación de C++, 101 reglas, pautas y mejores prácticas, Herb Sutter y Andrej Alexandrescu". Sin embargo, no existe un estándar de codificación oficial en C++. – patrik
- 1. C++: funciones virtuales privadas, frente a las funciones virtuales puras
- 2. funciones virtuales en C Objetivo
- 3. funciones virtuales estáticos en C++
- 4. ¿Debo declarar log4net logger una vez por clase o en la clase base?
- 5. ¿Debo implementar IDisposable en todas las clases, o es una clase base suficiente?
- 6. ¿Por qué las funciones virtuales en C++ se llaman 'virtuales'?
- 7. Evitar funciones virtuales
- 8. ¿Debo sellar todas las clases que sé que nunca deberían usarse como una clase base?
- 9. Declarar una variable global para usar en todas las actividades
- 10. funciones virtuales de objetos rebanar
- 11. Anular de forma segura las funciones virtuales de C++
- 12. Requerir funciones virtuales anuladas para llamar a implementaciones base
- 13. ¿Cuándo debo declarar session_start() ;?
- 14. Anulación de las funciones virtuales públicas con funciones privadas en C++
- 15. anulación de funciones no virtuales
- 16. con funciones virtuales
- 17. PHP cómo enumerar todas las funciones públicas de la clase
- 18. C++ pregunta sobre polimorfismo/herencia: redefinición de funciones base frente a funciones virtuales
- 19. ¿Dónde debo declarar las variables estáticas?
- 20. ¿Cuándo debería declarar las variables en una clase de PHP?
- 21. encasillamiento con funciones virtuales
- 22. Obtenga una lista de todas las funciones y procedimientos en una base de datos Oracle
- 23. C++ Implementación de funciones virtuales?
- 24. Tipo de devolución diferente para funciones virtuales
- 25. PHP: Wrap todas las funciones de una clase en una subclase
- 26. ¿Por qué usar funciones virtuales?
- 27. eliminar todas las variables, excepto las funciones
- 28. clase tiene funciones virtuales y destructor no virtual accesible
- 29. Variable de referencia y funciones virtuales
- 30. ¿Las funciones virtuales no puras con los parámetros son una mala práctica?
Cuando al menos un método es virtual en una clase, debe tener el destructor virtual. – stefanB