2009-06-05 11 views
22

Estoy tratando de usar las funciones de miembros en línea de una clase en particular. Por ejemplo, la declaración de la función y la aplicación sin procesos en línea es como tal:error del enlazador de la función en línea

en el archivo de cabecera:

int GetTplLSize(); 

en el archivo .cpp:

int NeedleUSsim::GetTplLSize() 
{ 
    return sampleDim[1]; 
} 

Por alguna razón, si pongo el " palabra clave "en línea" en cualquiera de la implementación y declaración, así como en ambos lugares, obtengo errores de enlazador como se muestra:

 
Creating library C:\DOCUME~1\STANLEY\LOCALS~1\TEMP\MEX_HN~1\templib.x and object C:\DOCUME~1\STANLEY\LOCALS~1\TEMP\MEX_HN~1\templib.exp 
mexfunction.obj : error LNK2019: unresolved external symbol "public: int __thiscall NeedleUSsim::GetTplLSize(void)" ([email protected]@@QAEHXZ) referenced in function _mexFunction 
mexfunction.mexw32 : fatal error LNK1120: 1 unresolved externals 

    C:\PROGRA~1\MATLAB\R2008B\BIN\MEX.PL: Error: Link of 'mexfunction.mexw32' failed. 

Lo que debe ser necesario para deshacerse de este error (es decir ¿Qué estoy haciendo mal en términos de hacer estas funciones miembros en línea)?

Respuesta

23

Luego debe colocar la definición de la función en el encabezado. La forma más sencilla de hacer alusión al compilador en línea es incluir un cuerpo de método en la declaración de clase como:


class NeedleUSsim 
{ 
    // ... 
    int GetTplLSize() const { return sampleDim[1]; } 
    // ... 
}; 

o, si insiste en declaración por separado y definición:


class NeedleUSsim 
{ 
    // ... 
    int GetTplLSize() const; 
    // ... 
}; 

inline int NeedleUSsim::GetTplLSize() const 
{ return sampleDim[1]; } 

La definición tiene que haber visible en cada unidad de traducción que usa ese método.

+0

¿Es esta la única manera? (Quiero separar la declaración y la implementación por separado por razones de legibilidad) – stanigator

+1

Básicamente sí. El compilador debe conocer el cuerpo de la función al compilar las llamadas, por lo que el cuerpo debe estar en el archivo de encabezado incluido. Sin embargo, aún podría declarar la función en la declaración de clase y agregar la implementación en un lugar posterior en el archivo de encabezado. – Hans

+0

Ya veo. Supongo que tendré que vivir escribiendo el código de esta manera. Gracias por los consejos. – stanigator

2

Si tiene una función en línea, debe poner la definición en el archivo de encabezado.

+0

Intenté poner la palabra clave en línea en las definiciones en el archivo de encabezado y sigo teniendo el mismo error de enlazador. – stanigator

+2

No solo la palabra clave en línea, toda la definición debe ir en el archivo de encabezado. Por lo tanto, muévelo desde su archivo .cpp a su archivo .h. – ChrisInEdmonton

+1

Definición, no declaración. –

17

de C++ FAQ Lite

Si pones la definición de la función en línea en un archivo .cpp, y si se llama desde algún otro archivo .cpp, obtendrá un "externo no resuelto " error del vinculador.

How do you tell the compiler to make a member function inline?

+0

, lamentablemente, como acabo de descubrir por las malas, este NO es el caso en MSVC 2013 y 2015. Tuve un en línea en un archivo CPP (en una biblioteca), y su código fue llamado desde un código fuente de CPP totalmente diferente que tiene una línea propia con el mismo nombre (pero un código ligeramente diferente, por lo que el resultado rompió las pruebas). Considero que es un error en ese entorno de desarrollo. Difícil de encontrar... – chksr

3

Como otros ya han señalado, tiene que mover la definición de la función inline en el fichero de cabecera, así:

class NeedleUSsim 
{ 
    // ... 
    inline int GetTplLSize() { return sampleDim[1]; } 
    // ... 
}; 

La razón de esto es que el el compilador necesita saber qué código incluir cuando ve una llamada a la función en línea. Si deja la definición de la función en el archivo .cpp para la clase NeedleUSsim, el código que genera el compilador queda atrapado en el archivo de objeto NeedleUSsim. Como el compilador solo lee el código fuente —, nunca se asoma al archivo de objetos de otra clase —, simplemente no tiene forma de saber con qué código reemplazar una llamada cuando está compilando otro archivo .cpp.

0

Ver el Inline Guard Macro idiom. Esto al menos le permitirá separar, aunque ligeramente, el código de la declaración. También le permite alternar la alineación de funciones a través de define.

Cuestiones relacionadas