30 votos

C++ de la función de miembro inline .archivo cpp

Sé que en línea funciones miembro, por definición, debe ir en el encabezado. Pero ¿y si no es posible poner la implementación de la función en el encabezado? Veamos en esta situación:

Archivo A. h

#pragma once
#include "B.h"

class A{
    B b;
};

El archivo B. h

#pragma once

class A; //forward declaration

class B{
    inline A getA();
};

Debido a la circular incluyen tengo que poner a la implementación de getA en

B.cpp

#include "B.h"
#include "A.h"

inline A B::getA(){
    return A();
}

Será el compilador en línea getA? Si es así, que en línea de palabras clave es el significante (el uno en el encabezado o el uno en el .archivo cpp)? Hay otra forma de poner la definición de una línea de función miembro en su .archivo cpp?

33voto

Arun Puntos 6838

Citando a de C++ FAQ:

Nota: Es imperativo que la la definición de la función (la parte entre {...}) ser colocado en un archivo de encabezado, a menos que la función es se utiliza sólo en una sola .archivo cpp. En en particular, si se pone el en línea la definición de la función en un .archivo cpp y desde el otro .cpp archivo, recibirá un "sin resolver externo" error del vinculador.

El compilador necesita para ver la definición de la función en línea cada vez que encuentra cualquier uso de esa función en línea. Que es normalmente posible si la función en línea se coloca en un archivo de encabezado.

Será el compilador en línea getA?

No, excepto cuando el uso de getA() está en B.cpp sí.

Si es así, que en línea de palabras clave es el significante (el uno en el encabezado o en el cpp)?

Mejor práctica: sólo en la definición fuera del cuerpo de la clase.

Hay otra forma de poner la definición de una línea de función miembro en su archivo cpp?

No, al menos yo no lo sé.

11voto

EboMike Puntos 39257

No puede, fuera del alcance de B.cpp. El compilador funciona por la compilación de la base de la unidad, es decir, que se compila cada uno .archivo cpp de forma individual, por lo que si se compila C.cpp, no tener el código para getA() disponibles y deben realizar una llamada a una función y que el vinculador arreglar (o, si realmente tomó la palabra y trató en línea, tendrá terminar con un error del vinculador. inline tiene cualidades similares como static).

La única excepción es LTCG, es decir, el enlace en tiempo de generación de código, que está disponible en los nuevos compiladores.

Un enfoque en este caso es tener otro archivo de encabezado (a veces con el nombre *.inl archivos) que contiene la línea de código.

EDIT: Como para que en línea es relevante - es el que está en la definición de la clase, es decir, en el archivo de encabezado. Tenga en cuenta que muchos de los compiladores tienen su propia opinión sobre lo que puede y debe estar en línea. gcc, por ejemplo, puede desactivar la función inline completamente (-O0), o puede en línea nada que considere que vale la pena inline (como -O3).

6voto

Loki Astari Puntos 116129

Me gustaría ir sobre esto desde la dirección opuesta.

No agregue en línea de las declaraciones de su función (a menos que sea necesario).

La única vez que usted necesita para agregar la línea de la declaración de una función/método es que si la función de definir en un archivo de encabezado, pero fuera de la declaración de la clase.

X. h

class X
{
    public:
        int getX()   { return 4;} // No inline because it is part of the class.
                                  // The compiler knows that needs an inline tag
        int getY();
        int getZ();
};

inline
int X::getY()  { return 5;}       // This needs to be explicitly declared inline.
                                  // Otherwise the linker will complain about
                                  // multiple definitions in compilation units.

X.cpp

 // Never declare anything inline in the cpp file.

 int X::getZ() { return 6; }

Para más caso específico.
Quitar toda la línea de especificaciones. Ellos no están haciendo lo que usted piensa que ellos están haciendo.

5voto

IfLoop Puntos 59461

En estos días, la mayoría de los compiladores pueden realizar alineaciones en el momento de enlazar, así como el tiempo de compilación. Si su función es probable que se beneficien de alineaciones, a continuación el Enlace de Tiempo es probable que el optimizador de hacer precisamente eso.

Por el momento el vinculador llega a ella, no se mucho acerca de la línea de estado de la salida del compilador, a excepción de que el compilador de la bandera de ciertos objetos coleccionables, por ejemplo debido a una función en línea o clase de instancia de plantilla, aparece en varias unidades de compilación, o se producirá un error cuando varios símbolos comparten un nombre, tal como la principal función que se definen dos veces. Nada de esto tiene influencia sobre el código real que se va a generar.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X