studio reales proyectos programacion libro introducción incluye herramientas fundamentos fuente español código con avanzado aplicaciones c++ performance inline getter-setter

c++ - reales - libro de android studio en español pdf



¿Es una buena práctica hacer "getters" y "setters" en línea? (11)

Al poner el código en el encabezado, está exponiendo su funcionamiento interno de clase. Los clientes pueden ver esto y hacer suposiciones sobre cómo funciona su clase. Esto puede hacer que sea más difícil cambiar su clase más tarde sin romper el código del cliente.

public: inline int GetValue() const { return m_nValue; } inline void SetValue(int nNewValue) { this -> m_nValue = nNewValue; }

En Learn C ++ , dijeron que funcionaría más rápido. Entonces, pensé que sería genial usarlo en getters y setters. Pero tal vez, hay algunos inconvenientes a eso?


El código se compilará un poco más y perderás la encapsulación. Todo depende del tamaño del proyecto y su naturaleza. En la mayoría de los casos, está bien hacerlos en línea si no tienen una lógica compleja.

Por cierto, puede omitir en inline si implementa directamente en la definición de la clase.


Esta es una mala práctica en las API públicas. Cualquier cambio en estas funciones requiere la recompilación de todos los clientes.

En general, si getters y setters muestran una abstracción pobre, no lo hagas. Si va constantemente a los datos brutos en otra clase, probablemente necesite reorganizar sus clases, en su lugar considere cómo desea manipular los datos dentro de una clase y proporcione los métodos apropiados para hacerlo.


La palabra clave en línea no tiene sentido en su caso

El compilador alineará su función si puede y quiere, independientemente de la palabra clave.

La palabra clave en línea afecta a la vinculación y no a la línea. Es un poco confuso, pero lee en él.

Si la definición está en una unidad de compilación diferente (archivo de origen después del preprocesador, básicamente) que la llamada, la alineación solo será posible si se habilitan la optimización del proyecto completo y la generación de código de tiempo de enlace. Habilitarlo aumenta mucho el tiempo de vinculación (ya que prácticamente vuelve a compilar todo en el vinculador), pero obviamente puede mejorar el rendimiento. No estoy seguro si está activado o desactivado de manera predeterminada en GCC y VS.


No es necesario, ¡comienza a confiar en los compiladores, al menos para esas optimizaciones!
"Pero no siempre"


No hago referencia a nada hasta que un generador de perfiles me haya dicho específicamente que no incluir en línea genera un problema de rendimiento.

El compilador de C ++ es muy inteligente y casi con certeza alineará automáticamente una función tan simple como esta para usted. Y, por lo general, es más inteligente que usted y hará un trabajo mucho mejor al determinar qué debe incluirse o no.

Evitaría pensar acerca de qué hacer o no para ponerme en línea y enfocarme en la solución. Agregar la palabra clave en inline más adelante (que no es una garantía de BTW en línea) es muy fácil de hacer y los lugares potenciales se pueden encontrar fácilmente con un generador de perfiles.


Puntos negativos:

  1. El compilador es libre de ignorarte.

  2. Cualquier cambio en estas funciones requiere la recopilación de todos los clientes.

  3. Un buen compilador alineará funciones no alineadas de todos modos cuando sea apropiado.


Si los escribe dentro de la definición, se consideran en inline por defecto .

Esto significa que se les permitirá en varias unidades de compilación (ya que las definiciones de clase en sí mismas aparecen típicamente en varias unidades de compilación), no es que realmente estén en línea.


También me gustaría añadir que, a menos que esté realizando millones de get / sets por frame, es prácticamente irrelevante si están en línea o no. Honestamente, no vale la pena perder el sueño.

Además, tenga en cuenta que el hecho de que coloque la palabra ''en línea'' delante de su declaración + declaración, no significa que el compilador insertará su código. Utiliza varias heurísticas para determinar si tiene sentido, que a menudo es la clásica compensación de la velocidad frente al tamaño. Sin embargo, existe la palabra clave ''__forceinline'' de fuerza bruta, en arrendamiento en VC ++ (no estoy seguro de qué se trata en GCC), que pisa fuerte en la sofisticada heurística de los compiladores. Realmente no lo recomiendo en absoluto, y además una vez que el puerto a una arquitectura diferente, es probable que sea incorrecta.

Intenta poner todas las definiciones de funciones en el archivo de implementación y deja las declaraciones puras para los encabezados (a menos que seas metaprogramación de plantillas (STL / BOOST / etc), en cuyo caso, casi todo está en los encabezados;))

Uno de los lugares clásicos a los que les gusta estar en línea (al menos en los videojuegos, que es de donde soy), está en los encabezados matemáticos. Los productos cruzados / puntos, las longitudes de vectores, el borrado de matrices, etc. a menudo se colocan en el encabezado, lo cual creo que es innecesario. 9/10 no hace ninguna diferencia en el rendimiento, y si alguna vez necesitas hacer un ciclo cerrado, como transformar una gran matriz de vectores por alguna matriz, probablemente es mejor hacer los cálculos en línea manualmente, o incluso mejor codificarlos en ensamblador específico de la plataforma.

Ah, y otro punto, si sientes que realmente necesitas que una clase sea más información que código, considera usar una buena vieja estructura, que no traiga el bagaje de abstracción de OO, eso es lo que está ahí. :)

Perdón, no quería seguir tanto, pero creo que ayuda tener en cuenta los casos de uso del mundo real, y no preocuparse demasiado por la configuración pedante del compilador (créanme, he estado allí;))

Buena suerte.

Shane


Tengo que decir que no tengo la fuerte aversión a esta práctica que otros en este hilo parecen tener. Estoy de acuerdo en que la ganancia de rendimiento de la línea es insignificante en todos los casos, excepto en los más utilizados. (Y sí, me he encontrado con tales casos en la práctica.) Cuando hago este tipo de alineación, lo hago por conveniencia, y en general solo para frases ingenuas como esta. En la mayoría de mis casos de uso, la necesidad de evitar la recompilación en el lado del cliente si alguna vez los cambio no es tan fuerte.

Sí, puede soltar la inline , como está implícito en la ubicación de la implementación.

Además, estoy un poco sorprendido por la vehemencia contra los usuarios. Difícilmente se puede estornudar en una clase en cualquier idioma de OO sin bajar un poco, y después de todo son una técnica válida para la implementación abstracta de la interfaz, por lo que es un poco masoquista afirmar que es una mala práctica de OO. Es un buen consejo no escribir accesos indiscriminadamente, pero también te aconsejo que no te dejes llevar por el celo para erradicarlos.

Toma eso, puristas. :-)