2

我有一个继承自非模板父类的模板类Child。当我在多个 .cpp 文件中包含Child的标头时,我收到 LNK2005 错误。发生这种情况是因为Parent在多个编译单元中定义。当这些单元链接在一起时,它们会导致 LNK2005 错误。

如果您想知道,Parent的目的是为Child的所有Child实例提供一个静态变量,而不仅仅是为每个Child< ''type'' >提供一个。

我的问题是,如何创建一个具有唯一(跨所有实例)静态变量并且可以包含在多个 .cpp 文件中的模板类?

这是导致此 LNK2005 错误的玩具示例:

主文件

#include "Apple.h"
#include "Banana.h"

#include <string>

void main() {
    Apple apple;
    Banana banana;
}

苹果.h

#ifndef APPLE_H
#define APPLE_H

struct Apple {
    Apple();
};

#endif // APPLE_H

苹果.cpp

#include "Apple.h"
#include "Child.h"

Apple::Apple() {
    Child<int> child;
    child.foo(5);
}

香蕉.h

#ifndef BANANA_H
#define BANANA_H

struct Banana {
    Banana();
};

#endif // BANANA_H

香蕉.cpp

#include "Banana.h"
#include "Child.h"

Banana::Banana() {
    Child<double> child;
    child.foo(3.14);
}

孩子.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:“受保护:静态 int Parent::id”(?id@Parent@@1HA) 已在 Apple.obj 中定义

4

2 回答 2

6

int Parent::id = 0;只需在Child.C. 通过将它包含在标题中,每个包含标题的文件都会定义一次。

我想我应该注意,在将其放入Parent.C(匹配类名)或Child.C匹配标题名称的弊端之间,我选择了一致性。更好的是放入Parent自己的文件中,以便您可以将定义放入一个恰当命名的名称Parent.C中,该名称仍与相应的标题名称匹配。

于 2011-03-22T18:16:17.210 回答
1

int Parent::id = 0;

出来Parent.cpp,你会没事的。现在发生的情况是,每个包含Child.h.

于 2011-03-22T18:17:06.750 回答