0

ライブラリ(alibrary.lib)にヘッダーファイルがあります。ライブラリは静的ライブラリ(.lib)であり、exeに適切にリンクします。

今、私はクラスVector3dを持っています。

class Vector3d 
{
    void amethod()
    {
       blah
    }

};

Vector3d cross(const Vector3d &v0, const Vector3d &v1) 
{
      float x,y,z;

      x = v0.y*v1.z-v0.z*v1.y;
      y = v0.z*v1.x-v0.x*v1.z;
      z = v0.x*v1.y-v0.y*v1.x;

     return Vector3d(x,y,z);

}

Vector3dは、ヘッダーファイル(Vector3d .h)で宣言および定義されています。クラス宣言の後、私はクロス関数です。

libコンパイルはファイルですが、単体テストexeにリンクすると、次のエラーが発生します。

 flywindow.obj :error LNK2005: "class Vector3d __cdecl cross(class Vector3d const &,class Vector3d const &)" (?cross@@YA?AVVector3d@@ABV1@0@Z) already defined in fly.obj

何か案は?

ありがとう

4

2 に答える 2

2

無料の (クラスのメンバーではない) 関数を定義する場合は、個別にコンパイルされた .cpp ファイルで定義するか、ヘッダーでインラインとしてマークする必要があります。したがって、あなたの場合、次のようにしてコンパイルすることを回避できます。

inline Vector3d cross(const Vector3d &v0, const Vector3d &v1) {
      float x,y,z;

      x = v0.y*v1.z-v0.z*v1.y;
      y = v0.z*v1.x-v0.x*v1.z;
      z = v0.x*v1.y-v0.y*v1.x;

     return Vector3d(x,y,z);

}

ヘッダーに関数の定義があるが、インラインでマークしていないため、エラーが発生します。別々にコンパイルされた 2 つのファイルにそのヘッダーをインクルードすると、コンパイルされたオブジェクト ファイルをリンクしようとすると、リンカーはエラーをスローします。

クラス定義内で定義されたメンバー関数は暗黙的にインライン化されるため、クラスのメンバー関数を明示的にインライン化することなく機能します。

ただし、一般に、ヘッダーで関数定義を作成することはお勧めできません。関数がベクター以外の型に依存する場合 (あなたの場合は問題ありませんが、もちろん議論の余地があります - 一部の人々はそれを好まない)、それらの型のヘッダーを含める必要があります。これにより、ヘッダーに間接的に含まれるコードが不必要に肥大化します。代わりに、そのような場合は、関数の宣言のみをヘッダー内に置くだけです。

Vector3d cross(const Vector3d &v0, const Vector3d &v1);

ただし、個別にコンパイルされた .cpp ファイル内で定義してください。もちろん、インラインは削除する必要があります。


関数とクラスにとって宣言と定義が何を意味するかを明確にするために、定義と宣言の小さなリストを追加さ​​せてください。すべての定義は宣言でもありますが、その逆ではないことに注意してください。

// class _declaration_ of boo
class boo;

// class _definition_ of foo.
class foo {
    // member function _declaration_ of bar
    void bar();

    // member function _definition_ of baz
    void baz() { }
};

// function _definition_ of fuzz
inline void fuzz() { }

// function _declaration_ of fezz
void fezz();
于 2009-02-01T04:14:32.330 に答える
1

最も可能性の高い説明は、インクルード ファイルにコード (具体的には cross の定義) があり、インクルード ファイルが 2 つのソース ファイルによってインクルードされているため、二重定義になっていることです。

ヘッダー ファイルには、定義ではなく、宣言が含まれている必要があります。宣言 (何かが存在することを示す) は、typedef、クラス宣言、enum などです。

定義 (存在するものに意味を与える) は、関数、可変定義などのようなものです。

クロス関数は、ヘッダー ファイルで宣言する必要があります。

Vector3d cross(const Vector3d &v0, const Vector3d &v1);

ただし、別のソース ファイルで定義されています。

于 2009-02-01T04:12:09.823 に答える