una palabras palabra keywords google ejemplos definicion claves clave cientifico articulo analizar analisis adwords c++ methods coding-style virtual-method

c++ - keywords - palabras clave seo



Estilo C++: Prefijo de palabra clave virtual para reemplazar los métodos (6)

He estado conversando con mis compañeros de trabajo sobre si prefijar los métodos anulados con la palabra clave virtual, o solo en la clase base de origen.

Tiendo a prefijar todos los métodos virtuales (es decir, métodos que implican una búsqueda vtable) con la palabra clave virtual. Mi razonamiento es triple:

  1. Dado que C ++ carece de una palabra clave override, la presencia de la palabra clave virtual, al menos, le notifica que el método implica una búsqueda y podría teóricamente ser anulado por especializaciones adicionales, o podría llamarse a través de un puntero a una clase base superior.

  2. Usar este estilo consistentemente significa que, cuando ve un método (al menos dentro de nuestro código) sin la palabra clave virtual, inicialmente puede asumir que no se deriva de una base ni está especializado en una subclase.

  3. Si, a través de algún error, los virtuales se eliminaron de IFoo, todos los niños seguirán funcionando (CFooSpecialization :: DoBar aún anularía CFooBase :: DoBar, en lugar de simplemente ocultarlo).

El argumento en contra de la práctica, tal como lo entendí, fue: "Pero ese método no es virtual" (que creo que es inválido, y se debe a un malentendido de la virtualidad), y "Cuando veo la palabra clave virtual, espero que significa que alguien se está derivando de él, y vaya a buscarlos ".

Las clases hipotéticas pueden distribuirse en varios archivos, y hay varias especializaciones.

class IFoo { public: virtual void DoBar() = 0; void DoBaz(); }; class CFooBase : public IFoo { public: virtual void DoBar(); // Default implementation void DoZap(); }; class CFooSpecialization : public CFooBase { public: virtual void DoBar(); // Specialized implementation };

Estilísticamente, ¿eliminarías la palabra clave virtual de las dos clases derivadas? Si es así, ¿por qué? ¿Cuáles son los pensamientos de Stack Overflow aquí?


Agregar virtual no tiene un impacto significativo de ninguna manera. Tiendo a preferirlo, pero en realidad es un tema subjetivo. Sin embargo, si se asegura de utilizar las palabras clave de override y sealed en Visual C ++ , obtendrá una mejora significativa en la capacidad de detectar errores en tiempo de compilación.

Incluyo las siguientes líneas en mi PCH:

#if _MSC_VER >= 1400 #define OVERRIDE override #define SEALED sealed #else #define OVERRIDE #define SEALED #endif


Estoy completamente de acuerdo con tu razonamiento. Es un buen recordatorio de que el método tendrá una semántica dinámica de envío cuando se llame. El argumento de "ese método no es virtual" que está utilizando su compañero de trabajo es completamente falso. Ha mezclado los conceptos de virtual y puro-virtual.


Puedo pensar en una desventaja: cuando una función miembro de la clase no se anula y usted declara que es virtual, agrega una entrada no necesaria en la tabla virtual para esa definición de clase.


Tiende a no utilizar ninguna sintaxis que el compilador me permita omitir. Habiendo dicho eso, parte del diseño de C # (en un intento de mejorar sobre C ++) fue exigir que las anulaciones de los métodos virtuales se etiquetaran como "anular", y eso parece ser una idea razonable. Mi preocupación es que, dado que es completamente opcional, es solo cuestión de tiempo antes de que alguien lo omita, y para entonces habrá adquirido el hábito de esperar que las anulaciones sean especificadas "virtuales". Tal vez lo mejor es vivir dentro de las limitaciones del idioma, entonces.


Una función una vez virtual siempre una virtual .

Por lo tanto, en cualquier caso, si la palabra clave virtual no se utiliza en las clases subsiguientes, no impide que la función / método sea ''virtual'', es decir, que se anule. Entonces, uno de los proyectos en los que trabajé tenía la siguiente pauta que me gustaba un poco:

  • Si se supone que la función / método debe ser anulado siempre use la palabra clave ''virtual''. Esto es especialmente cierto cuando se usa en clases de interfaz / base.
  • Si se supone que la clase derivada debe ser subclasificada, explíquese aún más la palabra clave ''virtual'' para cada función / método que pueda anularse. C ++ 11 usa la palabra clave ''anular''
  • Si no se supone que la función / método en la clase derivada se subclasificará nuevamente, la palabra clave ''virtual'' se comentará indicando que la función / método fue anulado pero no hay más clases que lo sobreescriban nuevamente. Por supuesto, esto no impide que alguien anule en la clase derivada a menos que la clase se haga definitiva (no derivable), pero indica que el método no debe ser anulado. Ej: /*virtual*/ void guiFocusEvent(); C ++ 11, utilice la palabra clave ''final'' junto con la ''anulación'' Ex: void guiFocusEvent() override final;

Nota: Mi respuesta se refiere a C ++ 03, que algunos de nosotros todavía estamos atrapados. C ++ 11 tiene la override y las palabras clave final como @JustinTime sugiere en los comentarios que probablemente deberían usarse en lugar de la siguiente sugerencia.

Ya hay muchas respuestas y dos opiniones contrarias que se destacan más. Quiero combinar lo que @ 280Z28 mencionó en su respuesta con la opinión de @ StevenSudit y las pautas de estilo de @ Abhay.

No estoy de acuerdo con @ 280Z28 y no usaría las extensiones de lenguaje de Microsoft a menos que esté seguro de que solo usará ese código en Windows.

Pero me gustan las palabras clave. Entonces, ¿por qué no simplemente usar una adición de palabras clave # define-d para mayor claridad?

#define OVERRIDE #define SEALED

o

#define OVERRIDE virtual #define SEALED virtual

La diferencia es su decisión sobre lo que quiere que suceda en el caso que describe en su 3er punto.

3 - Si, a través de algún error, los virtuales se eliminaron de IFoo, todos los niños seguirán funcionando (CFooSpecialization :: DoBar aún anularía CFooBase :: DoBar, en lugar de simplemente ocultarlo).

Aunque yo diría que es un error de programación, entonces no hay "solución" y probablemente ni siquiera deberías molestarte en mitigarlo, pero debes asegurarte de que se cuelgue o notifique al programador de alguna otra manera (aunque no puedo pensar en uno correcto). ahora).

Si elige la primera opción y no le gusta agregar #define , puede usar comentarios como:

/* override */ /* sealed */

Y eso debería hacer el trabajo para todos los casos en que desee claridad , porque no considero que la palabra virtual sea ​​lo suficientemente clara para lo que quiere que haga.