C ++:ヘッダー機能は、exeファイルにライブラリーから適切にリンクされていません
-
20-08-2019 - |
質問
私は図書館(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)で定義されています。クラス宣言、Iクロス機能した後。
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
任意のアイデア?
おかげ
解決
、それは別々にコンパイル.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つのファイルにそのヘッダーが含まれている場合、それは2回定義されているクロス機能を見ているので、リンカは、コンパイルされたオブジェクトファイルをリンクしようとすると、エラーをスローします。
クラス定義内で定義されているメンバ関数は、暗黙のうちに、インラインであるため、これは、exlicitlyクラスのメンバ関数のインラインをかけることなく動作します。
これは、一般的に良いアイデアは、ヘッダーに関数定義をしないように、しかし、です。あなたの関数は単なるベクトル以外のタイプ(あなたのケースで、それは罰金私見だが、それは当然の議論の余地だ - 何人かの人々がそれを好きではない)に依存する場合は、それらのタイプのヘッダーを含めるために必要とされるであろう。それは不必要に間接的にあなたのヘッダーに含まれますコードを膨張させます。
:代わりに、それらの例には、あなたは、単にヘッダ内のあなたの関数の唯一の宣言を置きます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();
他のヒント
最も可能性の高い説明は、あなたのファイルをインクルードして、ファイルを含めるには、コード(クロスの具体的な定義を)持っていることである2つのソースファイル、したがって、二重定義に含まれている。
ヘッダ・ファイルは、その中の宣言ではなく、定義を持っている必要があります。 (何かが存在することをsyaing)宣言はこれにtypedefでの、クラス宣言、列挙型のとのようなものです。
の定義(存在THOS事に意味を与えては)ように機能し、varialble定義とのようなものです。
あなたのクロス機能がヘッダファイルで宣言する必要があります:
Vector3d cross(const Vector3d &v0, const Vector3d &v1);
が、別々のソースファイルに定義されます。