我有一个模板类 Child ,它继承自非模板 Parent 类。当我在多个.cpp文件中包含 Child 的标头时,我收到LNK2005错误。发生这种情况是因为 Parent 在多个编译单元中定义。当这些单元链接在一起时,它们会导致LNK2005错误。
如果您想知道,父的目的是为所有 Child 实例提供 Child 一个静态变量,而不只是一个对于每个孩子< ''输入''> 。
我的问题是,如何创建一个具有唯一(跨所有 Child 实例)静态变量的模板化类,并且可以包含在多个.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);
}
Banana.h
#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:已在Apple.obj中定义的“protected:static int Parent :: id”(?id @ Parent @@ 1HA)
答案 0 :(得分:6)
您需要在int Parent::id = 0;
中定义一次Child.C
。通过将其包含在标题中,每个包含标题的文件都会定义一次。
我想我应该注意,在将它放入Parent.C
(匹配的类名)或Child.C
匹配标题名称的邪恶之间,我选择了一致性。更好的方法是将Parent
放在自己的文件中,这样就可以将定义放在一个恰当名称的Parent.C
中,它仍然与相应的标题名称相匹配。
答案 1 :(得分:1)
拉
int Parent::id = 0;
进入Parent.cpp
,你会没事的。现在发生的事情是,每个包含Child.h
的翻译单元都会包含一次定义。