Pregunta

Estoy escribiendo una clase Vector3D que llama a un método estático en una clase VectorMath para realizar un cálculo. Cuando compilo, obtengo esto:

bash-3.1$ g++ VectorMath.cpp Vector3D.cpp
/tmp/cc5cAPia.o: In function `main':
Vector3D.cpp:(.text+0x4f7): undefined reference to 'VectorMath::norm(Vector3D*)'
collect2: ld returned 1 exit status

El código:

VectorMath.h:

#ifndef VECTOR3D_H
#include "Vector3D.h"
#endif

class VectorMath {
    public:
    static Vector3D* calculatePerpendicularVector(Vector3D*, Vector3D*);
    static Vector3D* norm(Vector3D*);
    static double length(Vector3D*);
};

VectorMath.cpp

#include "VectorMath.h"
Vector3D* norm(Vector3D* vector) { // can't be found by linker
    // do vector calculations
    return new Vector3D(xHead, yHead, zHead, xTail, yTail, zTail);
}
// other methods

Vector3D.cpp

#include "Vector3D.h"
#include "VectorMath.h"
// ...
// vector implementation
// ...
int main(void) {
    Vector3D* v = new Vector3D(x, y, z);
    Vector3D* normVector = VectorMath::norm(v); // error here
}        

¿Por qué el enlazador no puede encontrar el método VectorMath :: norm ? A primera vista, pensaría que debería declarar una norma como esta:

Vector3D* VectorMath::norm(Vector3D* vector) {

pero eso tampoco ayuda ...

¿Fue útil?

Solución

Te estás perdiendo esto:

//VectorMath.cpp
#include "VectorMath.h"

             |
             V - here
Vector3D* VectorMath::norm(Vector3D* vector)
{
    ...
}

La función norma es parte de VectorMath :: . Sin eso, solo tienes una función gratuita.


Esto es más sobre tu diseño, pero ¿por qué estás usando punteros para todo? Esto es mucho más limpio:

class VectorMath {
    public:
    static Vector3D norm(const Vector3D&);
};

Toma referencias, estás en C ++, así que no escribas código C. ¿Qué sucede cuando llamo a esto?

VectorMath::norm(0); // null

Se bloqueará, tienes que poner un cheque, en cuyo caso, ¿qué debería devolver? Todo esto se limpia utilizando referencias.

Además, ¿por qué no hacer que estos miembros de la clase Vector3D ?

Vector3D* v = new Vector3D(x, y, z);
v->norm(); // normalize would be better, in my opinion

Por último, apilar las cosas. Su código ahora tiene una pérdida de memoria:

int main(void) {
    Vector3D* v = new Vector3D(x, y, z);
    Vector3D* normVector = VectorMath::norm(v); 

    // delete v;
    // ^ you're not deleting it!
}        

Cámbielo a esto y use conceptos RAII :

int main(void) {
    Vector3D v(x, y, z);
    Vector3D* normVector = VectorMath::norm(v);

    // delete v;
    // ^ you're not deleting it!
}    

Y al hacer que norma sea una función miembro, terminas con el código muy limpio:

int main(void) {
    Vector3D v(x, y, z);
    Vector3D normVector(v.norm());
}    

Sin punteros, sin filtraciones, todo sexy.

Otros consejos

No ha definido el método Vector3D :: norm en VectorMath.cpp . En su lugar, ha definido una función global llamada norma . Lo que debe hacer es calificar el nombre del método en la definición:

Vector3D* Vector3D::norm(Vector3D* vector)
Vector3D* VectorMath::norm(Vector3D* vector) { // can't be found by linker
    // do vector calculations
    return new Vector3D(xHead, yHead, zHead, xTail, yTail, zTail);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top