テンプレート以外のベースを備えたテンプレートクラスは、LNK2005エラーを提供します
-
28-10-2019 - |
質問
テンプレートクラスがあります 子 非テンプレートから継承します 親 クラス。含めるとき 子複数の.cppファイルのヘッダーは、LNK2005エラーを取得します。これは起こるからです 親 複数のコンピレーションユニットで定義されます。これらのユニットがリンクされると、LNK2005エラーが発生します。
あなたが疑問に思っている場合、の目的 親 与えることです 子 すべてに1つの静的変数 子 たとえば、それぞれに1つだけではありません 子<''タイプ ''>.
私の質問は、一意のテンプレートクラスを作成するにはどうすればよいですか(すべてにわたって 子 インスタンス)静的変数と複数の.cppファイルに含めることができますか?
これがこのLNK2005エラーを引き起こすおもちゃの例です。
main.cpp
#include "Apple.h"
#include "Banana.h"
#include <string>
void main() {
Apple apple;
Banana banana;
}
Apple.H
#ifndef APPLE_H
#define APPLE_H
struct Apple {
Apple();
};
#endif // APPLE_H
Apple.cpp
#include "Apple.h"
#include "Child.h"
Apple::Apple() {
Child<int> child;
child.foo(5);
}
バナナ
#ifndef BANANA_H
#define BANANA_H
struct Banana {
Banana();
};
#endif // BANANA_H
banana.cpp
#include "Banana.h"
#include "Child.h"
Banana::Banana() {
Child<double> child;
child.foo(3.14);
}
child.h
#ifndef CHILD_H
#define CHILD_H
#include <iostream>
using namespace std;
///////////// Parent Class Def ///////////
class Parent {
protected:
static int id;
};
int Parent::id = 0;
///////////// Child Class Def ///////////
template <class T>
struct Child : protected Parent {
Child();
void foo(T t);
};
template <class T>
Child<T>::Child() {
id++;
}
template <class T>
void Child<T>::foo(T t) {
cout << "Child" << id << "'s foo() says: " << t << endl;
}
#endif // CHILD_H
エラーLNK2005: "Protected:static int parent :: id"(?id@parent @@ 1ha)既にApple.objで定義されています
解決
定義する必要があります int Parent::id = 0;
一度だけ Child.C
. 。ヘッダーに含めることにより、ヘッダーを含むファイルごとに一度定義されます。
私はそれを入れることの悪の間にそれに注意すべきだと思います Parent.C
(一致するクラス名)または Child.C
ヘッダー名を一致させると、一貫性を選択しました。はるかに良いことです Parent
独自のファイルで、定義を適切な名前にすることができます Parent.C
対応するヘッダー名と一致します。
他のヒント
引く
int Parent::id = 0;
外に出ます Parent.cpp
そして、あなたは大丈夫です。今起こるのは、定義が翻訳ユニットごとに1回含まれることです。 Child.h
.