c++ - programador - linea de comandos avr
Respecto al espacio de nombres global en C++ (7)
Como los espacios de nombres no existen en C, no use :: HANDLE para acceder al tipo HANDLE.
El uso de prepending :: para el espacio de nombres global es una buena idea para facilitar la lectura, ya que sabe que el tipo al que desea acceder es desde el espacio de nombres global.
Además, si se encuentra en un espacio de nombres anidado y declara su propio tipo HANDLE (por ejemplo), entonces el compilador usará este en lugar de windows.h uno.
Por lo tanto, siempre prefiere usar :: antes de los nombres cuando se trabaja en el espacio de nombres anidado.
En C ++, ¿deberíamos estar preparando cosas en el espacio de nombres global con ::
?
Por ejemplo, cuando utilizo WinAPI, que está en C, debo hacer ::HANDLE
lugar de HANDLE
, y ::LoadLibrary
lugar de LoadLibrary
? ¿Qué dice C ++ sobre esto? ¿Es generalmente una buena idea, teniendo en cuenta cuestiones como la legibilidad y la capacidad de mantenimiento?
El principal punto de interés es cuáles son las diferencias desde el punto de vista del compilador, como ya se ha dicho, si incluye el ::
entonces está utilizando una búsqueda calificada, en lugar de una búsqueda no calificada.
La ventaja de utilizar una búsqueda calificada es que siempre podrá identificar un símbolo en particular. La desventaja es que siempre identificará ese símbolo en particular, es decir, deshabilitará la búsqueda dependiente del argumento. ADL es una parte importante y útil del idioma y, al calificarlo, lo deshabilitas de manera efectiva, y eso es malo.
Tenga en cuenta que tenía una función f
en el espacio de nombres global y que agregó un tipo T
dentro del espacio de nombres N
No consideres que quisieras agregar una sobrecarga de f
que tomaría una T
como argumento. Siguiendo el principio de la interfaz , puede agregar f
al espacio de nombres N
, ya que f
es en realidad una operación realizada en T
, y así pertenece al tipo. En este caso, si tenía un código que llamó (considere el código genérico) ::f(obj)
en un objeto de tipo desconocido U
el compilador no podrá detectar ::N::f(obj)
como una posible sobrecarga ya que el código solicita explícitamente una sobrecarga en el espacio de nombres global.
El uso de búsquedas no calificadas le brinda la libertad de definir las funciones a las que pertenecen, junto con los tipos que se utilizan como argumentos. Si bien no es exactamente lo mismo, considere el uso de swap
, si califica a std::swap
entonces no retomará su void swap( T&, T& )
enrollado a mano dentro de su espacio de nombres N
...
Solo calificaría completamente los identificadores cuando, de lo contrario, el compilador no recogería el elemento que quiero.
Es en gran parte una cuestión de estilo; No hay problemas de rendimiento o eficiencia de los que hablar. Puede ser una buena práctica en grandes proyectos y proyectos que se pretenden compilar en muchas plataformas diferentes, ya que en estas circunstancias es más probable que se produzcan colisiones entre nombres globales y nombres en un espacio de nombres.
Los nombres en C ++ pueden ser calificados y no calificados. Existen diferentes reglas para la búsqueda de nombres calificados y no calificados. ::HANDLE
es un nombre calificado, mientras que HANDLE
es un nombre no calificado. Considere el siguiente ejemplo:
#include <windows.h>
int main()
{
int HANDLE;
HANDLE x; //ERROR HANDLE IS NOT A TYPE
::HANDLE y; //OK, qualified name lookup finds the global HANDLE
}
Creo que la decisión de elegir HANDLE
vs. ::HANDLE
es una cuestión de estilo de codificación. Por supuesto, como sugiere mi ejemplo, puede haber situaciones en las que la calificación sea obligatoria. Por lo tanto, también puede usar ::
si acaso, a menos que la sintaxis sea algo desagradable para usted.
No, si no tiene un método LoadLibrary
en su clase, no necesita usar el alcance global. De hecho, no debe usar el alcance global porque si más adelante agrega un LoadLibrary
a su clase, probablemente sus intenciones son anular la función global ...
Normalmente, no tiene que anteponer ::
para el espacio de nombres global. (Solo en algunas circunstancias realmente raras). En mi humilde opinión, perjudica la legibilidad, pero, por otro lado, probablemente no rompa su código
Pongo todo mi código en un espacio de nombres, y tiendo a preferir los encabezados de C ++ a los encabezados de C, por lo que los únicos símbolos que quedan en el espacio de nombres global tienden a ser de la API de Windows. Evito colocar símbolos de otros espacios de nombres en el espacio de nombres actual (por ejemplo, nunca he using namespace std;
), prefiriendo en cambio calificar las cosas explícitamente. Esto está en línea con la guía de estilo C ++ de Google .
Por lo tanto, me he acostumbrado a calificar las llamadas de función WinAPI con ::
por varias razones:
Consistencia. Para todo lo que se encuentre fuera del espacio de nombres actual, me refiero a él explícitamente (por ejemplo,
std::string
), ¿por qué no referirse explícitamente a las API de Windows (por ejemplo,::LoadLibraryW
)? El espacio de nombres de las API de Windows es el espacio de nombres global.Muchas de las funciones de WinAPI se nombran de forma genérica (por ejemplo,
DeleteObject
). A menos que esté muy familiarizado con el código que está leyendo, es posible que no sepa siDeleteObject
es una llamada a algo en el espacio de nombres actual o al API de Windows. Así, encuentro el::
aclara.Muchos marcos de Windows tienen métodos con los mismos nombres que las llamadas en bruto. Por ejemplo,
ATL::CWindow
tiene un métodoGetClientRect
con una firma ligeramente diferente a la GetClientRect deGetClientRect
. En este marco, es común que su clase se derive deATL::CWindow
, por lo tanto, en la implementación de su clase, es normal decir queGetClientRect
invoque el método ATL heredado y::GetClientRect
si necesita llamar a la función WinAPI. No es estrictamente necesario, ya que el compilador encontrará el correcto en función de la firma. Sin embargo, me parece que la distinción se aclara para el lector.
(Sé que la pregunta no era realmente sobre WinAPI, pero el ejemplo era en términos de WinAPI).