6

VectorMath クラスの静的メソッドを呼び出して計算を実行する Vector3D クラスを作成しています。コンパイルすると、次のようになります。

bash-3.1$ g++ VectorMath.cpp Vector3D.cpp
/tmp/cc5cAPia.o: 関数「main」内:
Vector3D.cpp:(.text+0x4f7): 'VectorMath::norm(Vector3D*)' への未定義の参照
collect2: ld が 1 つの終了ステータスを返しました

コード:

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
}        

VectorMath::normリンカがメソッドを見つけられないのはなぜですか? 一見すると、次のように規範を宣言する必要があると思います。

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

しかし、それも役に立ちません...

4

3 に答える 3

17

あなたはこれを見逃しています:

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

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

このnorm機能は の一部ですVectorMath::。それがなければ、無料の機能しかありません。


これはあなたの設計に関するものですが、なぜすべてへのポインターを使用しているのですか? これはもっときれいです:

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

あなたはC++を使っているので、Cコードを書かないでください。これを呼び出すとどうなりますか?

VectorMath::norm(0); // null

クラッシュするか、チェックを入れる必要があります。その場合、何を返す必要がありますか? これはすべて、参照を使用してクリーンアップされます。

Vector3Dまた、クラスのこれらのメンバーを作成しないのはなぜですか?

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

最後に、スタック割り当てを行います。現在、コードにメモリ リークがあります。

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

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

これを次のように変更し、RAIIの概念を使用します。

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

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

メンバー関数を作成normすると、非常にクリーンなコードになります。

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

ポインターもリークもありません。すべてセクシーです。

于 2009-07-31T01:51:57.723 に答える
4

Vector3D::normでメソッドを定義していませんVectorMath.cpp。代わりに、という名前のグローバル関数を定義しましたnorm。あなたがする必要があるのは、定義でメソッド名を修飾することです:

Vector3D* Vector3D::norm(Vector3D* vector)
于 2009-07-31T01:51:33.650 に答える
0
Vector3D* VectorMath::norm(Vector3D* vector) { // can't be found by linker
    // do vector calculations
    return new Vector3D(xHead, yHead, zHead, xTail, yTail, zTail);
}
于 2009-07-31T01:53:25.850 に答える