¿Por qué C++ no hace que los destructores sean virtuales por defecto para las clases que tienen al menos otra función virtual? En este caso, agregar un destructor virtual no me cuesta nada, y no tener uno es (¿casi?) Siempre un error. ¿Va a abordar C++ 0x esto?Por qué los destructores no son virtuales de forma predeterminada [C++]
Respuesta
No paga lo que no necesita. Si nunca lo borra a través del puntero base, es posible que no desee la sobrecarga de la llamada al destructor indirectamente.
Quizás estaba pensando que la mera existencia del vtable es el único gasto general. Pero también se debe considerar el envío de cada función individual, y si quiero hacer mi despacho de llamadas al destructor directamente, debería poder hacerlo.
Sería bueno de su compilador advertirle si alguna vez elimina un puntero base y esa clase tiene métodos virtuales, supongo.
Editar: Déjame sacar excelente comentario de Simon aquí: Salida this SO question en el código generado para los destructores. Como puede ver, también hay que considerar la sobrecarga de código.
Por la letra de la norma, una clase polimórfica con un destructor no virtual no es un error. Una acción específica realizada en un objeto de este tipo da como resultado un comportamiento indefinido, pero todo lo demás es perfectamente kosher. Entonces, dado el comportamiento, por lo demás indulgente, del estándar en términos de los errores que permite a los programadores, ¿por qué se le debe dar un trato especial al destructor?
Y tal cambio tendría costos, aunque en su mayoría triviales: la tabla virtual será un elemento más grande, y el despacho virtual asociado con las llamadas al destructor.
Según mi leal saber y entender, no, no hay ningún cambio en el comportamiento de los destructores a este respecto en C++ 11. Me imagino que diría algo en la sección sobre funciones especiales para miembros, pero no es así, y tampoco hay nada en la sección de funciones virtuales en general.
¿Hubo * alguna vez * un plan para hacer que los destructores virtuales sean los predeterminados en C++ 0x? Lo pregunto porque me encontré con este artículo: http://www2.research.att.com/~bs/C++0x_panel.pdf que dice que había en la parte inferior, pero no he podido encontrar más información al respecto. – jeffythedragonslayer
@dacode: No seguí las reuniones reales y otras cosas, así que no sé. De los cuatro "vergüenzas", solo el último fue realmente cambiado. No me sorprendería que alguien presentara una profecía para tal cambio, pero no puedo decir por qué fue rechazada. –
He aquí un ejemplo (no es que Recomiendo escribir dicho código):
struct base {
virtual void foo() const = 0;
virtual void bar() const = 0;
};
struct derived: base {
void foo() const {}
void bar() const {}
};
std::shared_ptr<base>
make_base()
{
return std::make_shared<derived>();
}
Este código es perfectamente bien que no presenta UB. Esto es posible porque std::shared_ptr
usa borrado de tipo; la llamada final al delete
eliminará un derived*
, incluso si el último std::shared_ptr
para desencadenar la destrucción es del tipo std::shared_ptr<void>
.
Tenga en cuenta que este comportamiento de std::shared_ptr
es no adaptado a la destrucción virtual; tiene una variedad de otros usos (por ejemplo, std::shared_ptr<FILE> { std::fopen(...), std::fclose }
). Sin embargo, dado que esta técnica ya es paga el costo de algunas indirecciones, algunos usuarios pueden no estar interesados en tener un destructor virtual para sus clases base. Eso es lo que "paga solo por lo que necesita" significa.
- 1. ¿Por qué los destructores virtuales (C++) no se aplican para una clase base
- 2. ¿Cómo funcionan los destructores virtuales?
- 3. ¿Se heredan los destructores virtuales?
- 4. ¿Qué son los métodos virtuales?
- 5. Destructores virtuales para las interfaces
- 6. ¿Cuándo no deberías usar destructores virtuales?
- 7. Funciones virtuales en constructores, ¿por qué los idiomas son diferentes?
- 8. ¿Son compatibles los goto y los destructores?
- 9. ¿Por qué las funciones virtuales en C++ se llaman 'virtuales'?
- 10. ¿Por qué se requieren destructores en C++?
- 11. ¿Por qué C++ std :: list :: clear() no llama a destructores?
- 12. Heredando de clases sin destructores virtuales
- 13. Campos virtuales de mangosta incluidos en JSON de forma predeterminada: schemaOptions.toJSON.virtuals = true; Todavía no incluye campos virtuales por defecto
- 14. ¿Cuáles son los usos de funciones virtuales puras en C++?
- 15. ¿Los métodos abstractos son virtuales?
- 16. ¿Por qué los idiomas no provocan errores en el desbordamiento de enteros de forma predeterminada?
- 17. ¿Por qué los métodos virtuales deben anularse explícitamente en C#?
- 18. ¿Por qué los métodos de interfaz C# no se declaran abstractos o virtuales?
- 19. Comportamiento extraño de los destructores de C++
- 20. ¿Por qué usar funciones virtuales?
- 21. ¿Por qué los navegadores modernos no son compatibles con los métodos de forma PUT y DELETE?
- 22. ¿Por qué mis clases son privadas de forma predeterminada en Visual Studio?
- 23. ¿Por qué std :: stack usa std :: deque de forma predeterminada?
- 24. ¿Por qué la implementación predeterminada == no llama igual?
- 25. ¿Por qué las aplicaciones WinForms STATread de forma predeterminada?
- 26. ¿Por qué los conjuntos de Python no son lavables?
- 27. hadoop solo lanza trabajo local de forma predeterminada ¿por qué?
- 28. ¿Por qué NFS usa UDP de forma predeterminada?
- 29. ¿Por qué los EJB son seguros y los servlets no?
- 30. ¿Podemos tener funciones virtuales estáticas? Si no, ¿POR QUÉ?
La palabra clave es 'casi'. Si su base tiene funciones virtuales y no quiere pagar por el destructor virtual, ¿cómo se especifica que no es virtual en este nuevo mundo? ¿Qué pasa con todo el código anterior? Necesitamos un plan para tratar los problemas de compatibilidad con versiones anteriores. –
El destructor virtual tiene un costo, ya que requiere otra copia del código del destructor para todas las clases derivadas. Ver [esta pregunta] (http://stackoverflow.com/questions/6613870/gnu-gcc-g-why-does-it-generate-multiple-dtors/6614903). –
posible duplicado de [¿Por qué no tiene todas las funciones como virtual en CPP] (http://stackoverflow.com/questions/6606657/why-not-have-all-the-functions-as-virtual-in-cpp) – iammilind