Pregunta

Si definimos una función miembro dentro de la propia definición de la clase, es necesariamente tratada en línea o es sólo una solicitud para el compilador que se puede pasar por alto.

¿Fue útil?

Solución

Sí, las funciones que se definen dentro de un cuerpo de la clase son implícitamente inline.

(Al igual que con otras funciones declaró inline Esto no significa que el compilador tiene que realizar la expansión en línea en lugares donde la función se llama, sólo permite la relajación de la "regla de definición de un" permitido, combinada con el requisito de que una definición debe ser incluido en todas las unidades de traducción que se utiliza la función.)

Otros consejos

Como se ha indicado por otros, un método definido dentro de una clase se solicita automáticamente inline. Es útil para entender por qué.

Supongamos que no lo eran. Habría que generar código para la función de tal, y en todas partes se le llama, un salto a subrutina instrucción tendría que hacer referencia a la ubicación, mediante el engarce.

class A {
public:
  void f() { ... your code ... }
};

Cada vez que este código se ve, si no es en línea, el compilador sólo puede asumir que se debe generar, por lo que generaría un símbolo. Supongamos que era así:

A__f_v:

Si ese símbolo era global, entonces si pasó a incluir el código de clase varias veces en diferentes módulos, que tendría un error de símbolos se multiplican definido en tiempo de enlace. Por lo que no puede ser global. En cambio, de archivos local.

Imagine que se incluye el archivo de cabecera por encima de una serie de módulos. En cada uno de ellos, que va a generar una copia local de ese código. ¿Qué es mejor que no compilar en absoluto, sino que está recibiendo múltiples copias del código cuando en realidad sólo uno necesita.

Esto lleva al siguiente conclusión: si el compilador no va a inline una función, que es significativamente mejor que la que se declara en alguna parte una vez, y no se le pedía que ser inline

.

Por desgracia, lo que es y no es en línea no es portátil. Es definido por el escritor del compilador. Una regla empírica buena es hacer siempre todo un trazador de líneas, en especial todas las funciones que a su vez acaba de llamar a una función, en línea, al quitarlos de encima. Cualquier cosa por debajo de tres líneas de código lineal es casi seguro que está bien. Pero si usted tiene un bucle en el código, la pregunta es si el compilador lo permitirá en línea, y más al punto, la cantidad de beneficios que se vería incluso si lo hiciera lo que quiere.

consideran este código en línea:

inline int add(int a, int b) { return a + b; }

No sólo es casi tan pequeño como el prototipo estaría en el código fuente, pero el lenguaje ensamblador generado por el código en línea es más pequeña que la llamada a una rutina sería. Por lo que este código es más pequeño y más rápido.

Y, si quedas pasando en constantes:

int c= add(5,4);

Se resuelve en tiempo de compilación y no hay ningún código.

En gcc, hace poco se dio cuenta de que, incluso si lo hago código no en línea, si es local a un archivo, lo harán a escondidas en línea de todos modos. Es sólo si declaro la función en un módulo de fuente separada que no es así optimizar la distancia a la llamada.

En el otro extremo del espectro, supongamos que usted solicita en línea en un pedazo 1000 línea de código. Incluso si su compilador es tan tonto como para ir junto con él, la única cosa que ahorra es la llamada en sí, y el costo es que cada vez que la llame, el compilador debe pegar todo ese código. Si se llama a ese código n veces , su código crece por el tamaño de la rutina * n. Así que cualquier cosa más grande que 10 líneas no es más o menos la pena procesos en línea, excepto en el caso especial en el que sólo se llama un número muy pequeño de veces. Un ejemplo de ello podría ser en un método privado llamado por sólo 2 otros.

Si solicita a inline un método contiene un bucle, que sólo tiene sentido si se ejecuta a menudo un pequeño número de veces. Pero considere un bucle que itera un millón de veces. Incluso si se colocarán en línea del código, el porcentaje de tiempo pasado en la llamada es muy pequeña. Así que si usted tiene métodos con bucles en ella, que tienden a ser más grande de todos modos, los que valen la eliminación del archivo de cabecera porque a) tenderán a ser rechazado como en línea por el compilador y b) incluso si fueron entre líneas, son por lo general no va a proporcionar ningún beneficio

Se trata necesariamente por el compilador como una solicitud de línea - que se puede pasar por alto. Hay algunas expresiones idiomáticas para la definición de algunas funciones en la cabecera (por ejemplo, vaciar destructores virtuales) y algunas definiciones necesario de cabecera (funciones plantilla), pero aparte de eso Ver GotW # 33 para más información.

Algunos han señalado que el compilador puede incluso funciones en línea que nunca se le ha pedido que, pero no estoy seguro de si eso sería contrario al propósito de solicitar a una función inline.

Está hecho inline -. Pero ninguna petición en línea puede ser ignorado por el compilador

Es una petición al compilador que se puede pasar por alto.

estándar El 2003 ISO C ++ dice

  

7.1.2 / 2 una declaración de función (8.3.5, 9.3, 11.4) con un inline   especificador declara un inline   función. El comitente en línea   indica a la aplicación que   sustitución en línea de la función de   cuerpo en el punto de llamada está siendo   preferente a la llamada a la función habitual
  mecanismo. Una implementación no es   requerido para realizar esta línea
  La sustitución en el punto de llamada;   Sin embargo, incluso si esta línea
  se omite la sustitución, el otro   reglas para funciones en línea definidas   por 7.1.2 todavía serán respetados.

     

función 7.1.2 / 3 A definido dentro de una definición de clase es un inline
  función. El comitente en línea deberá   no aparece en una función ámbito de bloque   declaración.

     

7.1.2 / 4 una función en línea se definirá en cada unidad de traducción en
  el que se utiliza, y tendrá   exactamente la misma definición en todos los
  caso (3,2). [Nota: una llamada a la   función en línea puede encontrarse
  antes de su defi-nición aparece en el   unidad de traducción. ] Si una función   con enlace externo se declara   inline en una unidad transla-ción, se   será declarado en línea en todo   unidades de traducción en el que se   aparece; No se requiere ningún diagnóstico. Un   función en línea con externo   vinculación tendrá la misma dirección en   todas las unidades de traducción. Un estática   variable local en una línea extern
  función se refiere siempre a la misma   objeto. Un literal de cadena en un
  extern función en línea es el mismo   objeto en traducción diferente
  unidades.

Hay dos cosas que no deben ser agrupados:

  1. ¿Cómo se marca una función que estar en línea: definirlo con línea frente a la firma o definirlo en el punto de declaración;
  2. ¿Qué el compilador tratará tal marca en línea:. Independientemente de lo que haya marcado la función como en línea que será tratada como una solicitud por el compilador
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top