2010-04-03 21 views
16

Tengo un proyecto favorito con el que experimento con las nuevas características de C++ 11. Si bien tengo experiencia con C, soy bastante nuevo en C++. Para capacitar a mí mismo en las mejores prácticas, (además de leer mucho), me he permitido algunas estrictos parámetros del compilador (usando GCC 4.4.1):¿Por qué enable_shared_from_this tiene un destructor no virtual?

-std=c++0x -Werror -Wall -Winline -Weffc++ -pedantic-errors 

Esto ha funcionado bien para mí. Hasta ahora, he podido resolver todos los obstáculos. Sin embargo, tengo una necesidad de enable_shared_from_this, y esto me está causando problemas. Me da la siguiente advertencia (error, en mi caso) al compilar mi código (probablemente provocada por -Weffc++):

base class ‘class std::enable_shared_from_this<Package>’ has a non-virtual destructor 

Así que, básicamente, soy un poco intervenidos por esta implementación de enable_shared_from_this, porque:

  • Un destructor de una clase que es previsto para la subclase siempre debe ser virtual, en mi humilde opinión.
  • El destructor está vacío, ¿para qué tenerlo?
  • No puedo imaginar que alguien quiera eliminar su instancia por referencia al enable_shared_from_this.

Pero estoy buscando maneras de lidiar con esto, así que mi pregunta es, ¿hay una forma adecuada de lidiar con esto? Y: ¿estoy en lo correcto al pensar que este destructor es falso, o hay un verdadero propósito para él?

+1

¿Has probado la herencia privada o protegida? ¿Cambia el diagnóstico? – Tomek

+0

Esa es una gran idea. Pero desafortunadamente, no es así. –

+1

'-WeffC++' desencadena muchas advertencias inútiles (en relación con la biblioteca) de la biblioteca estándar, y esto se menciona [en las preguntas frecuentes] (http://gcc.gnu.org/onlinedocs/libstdc++/faq.html # faq.wefcxx_verbose) –

Respuesta

23

Un destructor de una clase que está destinada a la subclasificación siempre debe ser virtual, en mi humilde opinión.

Un destructor virtual en una clase base solo es necesario si una instancia de la clase derivada se va a eliminar mediante un puntero a la clase base.

Tener cualquier función virtual en una clase, incluido un destructor, requiere una sobrecarga. Boost (y las bibliotecas estándar TR1 y C++ 11) no lo obligan a tener esa sobrecarga solo porque necesita poder obtener un shared_ptr desde el puntero this.

El destructor está vacío, ¿para qué tenerlo?

Si no tiene un constructor definido por el usuario, el compilador proporciona uno para usted, por lo que realmente no importa.

No me puedo imaginar que alguien quiera eliminar su instancia por referencia al enable_shared_from_this.

Exactamente.

En cuanto a la advertencia del compilador, ignoraría la advertencia o la suprimiría (con un comentario en el código explicando por qué lo está haciendo). Ocasionalmente, especialmente en niveles de advertencia "pedantes", las advertencias del compilador no son útiles, y yo diría que este es uno de esos casos.

9

estoy de acuerdo con la descripción de Jame, pero añadiría

un destructor virtual sólo es necesario si quieres destruir una instancia de esa clase de forma virtual. Esto no es siempre el caso, sin embargo, si una clase base no está destinado a ser destruido prácticamente se debe proteger contra ella

Así que cambiaría

un destructor de una clase que es destinado a la creación de subclases debe siempre ser virtual, en mi humilde opinión.

este a ser:

Un destructor de una clase que es destinado a subclases debe ser siempre virtual o protegida.

+0

Hmm ... buen punto. El destructor de 'enable_shared_from_this' en realidad está protegido. Entonces, quizás esto es un error en '-WeffC++ 'de GCC? –

+2

@ Shtééf: C++ efectivo dice que las bases polimórficas deben tener dtors virtuales, y las clases que no están destinadas para el polimorfismo no deben tener dtors virtuales. Como el compilador no puede decir cuál es cuál, diría que sí, es un error ofrecer esta advertencia. Entonces, o bien su implementación de IIRC el consejo sobre dtors protegidos en clases de base no polimórficas si de GotW/Exceptional C++, no es efectiva. –

+2

Además, mi versión de la página man gcc dice que la advertencia '-Wnon-virtual-dtor' es solo para clases con una función virtual. Entonces, 'enable_shared_from_this' tiene una función virtual (mi implementación no), o si la advertencia no sigue la documentación (que sería un error), o si los documentos han cambiado (revisa los tuyos, quizás expliquen la advertencia) promover). En realidad, es posible que * C++ * efectivo se haya actualizado: la página de manual de gcc cita títulos que no coinciden con mi 3ª edición.Así que podría decirse que es un error en el libro de Scott Meyers ;-) –

4

hay una manera adecuada para hacer frente a esto?

No utilice -Weffc++ todo el tiempo. Es útil activarlo algunas veces para verificar el código, pero no para usarlo de forma permanente. Da falsos positivos y realmente no se mantiene en estos días. Úselo de vez en cuando, pero tenga en cuenta que podría tener que ignorar algunas advertencias. Lo ideal sería que simplemente memorizar todos los consejos en los libros Meyers y entonces no lo necesita de todos modos ;-)

Estoy en lo correcto al pensar que este destructor es falso, o hay un verdadero propósito a ella?

No, no es falso y tiene un propósito real. Si no se definió, se declararía implicidad como public, para evitar que se declare explícitamente como protected.

Cuestiones relacionadas