Frage

Ich schreibe eine Vector3D-Klasse, die eine statische Methode einer VectorMath-Klasse aufruft, um eine Berechnung durchzuführen.Beim Kompilieren erhalte ich Folgendes:

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

Der 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
}        

Warum kann der Linker das nicht finden VectorMath::norm Methode?Auf den ersten Blick würde ich denken, dass ich eine Norm wie folgt deklarieren müsste:

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

aber das hilft auch nicht...

War es hilfreich?

Lösung

Das fehlt dir:

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

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

Der norm Funktion ist Teil von VectorMath::.Ohne das haben Sie nur eine kostenlose Funktion.


Hier geht es mehr um Ihr Design, aber warum verwenden Sie auf alles Zeiger?Das ist viel sauberer:

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

Nehmen Sie Referenzen, Sie sind in C++, also schreiben Sie keinen C-Code.Was passiert, wenn ich das anrufe?

VectorMath::norm(0); // null

Entweder stürzt es ab, Sie müssen einen Scheck einlegen. Was soll in diesem Fall zurückgegeben werden?Dies alles wird durch die Verwendung von Referenzen bereinigt.

Warum machen Sie diese Mitglieder nicht einfach zum Vector3D Klasse?

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

Zu guter Letzt: Dinge stapeln.Ihr Code weist derzeit einen Speicherverlust auf:

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

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

Ändern Sie es in dieses und verwenden Sie es RAII Konzepte:

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

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

Und durch das Machen norm Wenn Sie eine Mitgliedsfunktion verwenden, erhalten Sie den sehr sauberen Code:

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

Keine Hinweise, keine Lecks, alles sexy.

Andere Tipps

Sie haben nicht definiert Vector3D::norm Methode in VectorMath.cpp. Stattdessen haben Sie eine globale Funktion namens definiert norm. Was Sie tun müssen, ist, den Methodennamen in der Definition zu qualifizieren:

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);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top