2009-07-31 14 views
4

J'écris une classe Vector3D qui appelle une méthode statique sur une classe VectorMath pour effectuer un calcul. Quand je compile, je reçois ceci:Problèmes de lien C++ avec la méthode statique

 
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 

Le code:

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 
}   

Pourquoi ne peut pas l'éditeur de liens trouver la méthode VectorMath::norm? À première vue, je pense que je dois déclarer norme comme ceci:

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

mais cela ne suffit pas non plus ...

+0

Ceci: "mais cela n'aide pas non plus ..." n'est pas une information suffisante. Qu'est-ce que ça veut dire? Mêmes erreurs, différentes erreurs? – GManNickG

Répondre

14

vous manque ceci:

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

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

La fonction norm fait partie de VectorMath::. Sans cela, vous avez juste une fonction gratuite.


Ceci est plus sur votre conception, mais pourquoi utilisez-vous des pointeurs sur tout? C'est beaucoup plus propre:

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

Prenez des références, vous êtes en C++ donc n'écrivez pas de code C. Que se passe-t-il quand j'appelle ça? Il va soit tomber en panne, vous devez mettre un chèque, auquel cas, que devrait-il retourner? Tout est nettoyé en utilisant des références.

Aussi, pourquoi ne pas simplement faire ces membres de la classe Vector3D?

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

Enfin, empiler les choses.Votre bon code a maintenant une fuite de mémoire:

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

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

changement à cela, et utiliser RAII concepts:

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

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

Et en faisant norm une fonction de membre vous vous retrouvez avec le code très propre:

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

Aucun pointeur, aucune fuite, tous sexy.

+0

OK, merci, cela semble fonctionner. Je jure que j'ai essayé ça avant et ça a échoué - mais ça marche maintenant ... Merci pour les conseils sur la fuite de mémoire ... Je suppose que je vais poser une nouvelle question à propos de ces ... –

+0

@GMan, Impressive Answer :) – mahesh

4

Vous n'avez pas défini la méthode Vector3D::norm dans VectorMath.cpp. Au lieu de cela, vous avez défini une fonction globale nommée norm. Ce que vous devez faire est de qualifier le nom de la méthode dans la définition:

Vector3D* Vector3D::norm(Vector3D* vector) 
+0

Vous êtes 24 secondes plus rapide que moi. : [ – GManNickG

0
Vector3D* VectorMath::norm(Vector3D* vector) { // can't be found by linker 
    // do vector calculations 
    return new Vector3D(xHead, yHead, zHead, xTail, yTail, zTail); 
}