2011-01-22 14 views
38

Obtengo un error de compilación cuando intento alinear un método de una de mis clases. Funciona cuando elimino la palabra clave "en línea".C++ métodos de clase entrante causa referencia indefinida

Aquí está un ejemplo simplificado:

main.cpp:

#include "my_class.h" 

int main() { 
    MyClass c; 
    c.TestMethod(); 

    return 0; 
} 

my_class.h:

class MyClass { 
public: 
    void TestMethod(); 
}; 

my_class.cpp:

#include "my_class.h" 

inline void MyClass::TestMethod() { 
} 

Intento compilar con:

g++ main.cpp my_class.cpp 

me sale el error:

main.cpp:(.text+0xd): undefined reference to `MyClass::TestMethod()' 

Todo está bien si yo quite la "línea". ¿Qué está causando este problema? (y ¿cómo debo incluir los métodos de clase? ¿Es posible?)

Gracias.

Respuesta

3

Lo ha definido como no alineado en el archivo de encabezado, mientras que en el archivo cpp está tratando de definirlo como en línea. Esa es una definición en conflicto y no podrá encontrar una de la otra. Su encabezado es donde realmente coloca la palabra clave en línea.

Sin embargo, eliminaría la palabra clave en línea, ya que en realidad es más una sugerencia para el compilador. Realmente solo lo necesita cuando hay una función de libre flotación en el encabezado y no quiere que aparezcan múltiples definiciones en su base de códigos.

+0

'palabras clave inline' no son ciertamente solo una pista, al menos en C++: le dicen al compilador que debilite la definición y que la emita solo si es necesario. Esto significa que debe estar presente donde se usa, pero por otro lado se puede incluir más de una vez – bdonlan

+0

Aún recibo un error sin importar dónde coloque la línea (o si puse en línea ambas). De las 4 combinaciones (en línea en my_class.h y/o en my_class.cpp), solo funciona la que no tiene línea. – FrankMN

15

7.1.2/4 de la Norma:

An inline function shall be defined in every translation unit in which it is used...

Se utilizan TestMethod en main.cpp, pero no es definido allí.

... If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required.

Se define (y por lo tanto también se declaran) TestMethod en línea en my_class.cpp, pero no en main.cpp.

La solución en este caso es para mover la definición de la función en el fichero de cabecera, ya sea como esto:

class MyClass { 
public: 
    void TestMethod() {} 
}; 

o como esto:

class MyClass { 
public: 
    inline void TestMethod(); 
}; 

inline void MyClass::TestMethod() {}