テンプレート以外のベースを備えたテンプレートクラスは、LNK2005エラーを提供します

StackOverflow https://stackoverflow.com/questions/5395882

質問

テンプレートクラスがあります 非テンプレートから継承します クラス。含めるとき 複数の.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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top