我已经编写了我的程序,当我将所有内容保存在头文件中,然后使用我的主程序时,它就能正常工作。我现在将它们分成实现文件,但Eclipse一直给我错误。它在构造函数和函数的每个左大括号中都给出了错误。它在所有这些中都说“重新定义(构造函数或方法的名称),此处已在此处声明。”我做错了什么,因为它在头文件中有效?
#include "KeyValuePair.h"
template<typename Key,typename Value>
KeyValuePair<Key,Value>::KeyValuePair()
{ // error here
}
template<typename Key,typename Value>
void KeyValuePair<Key,Value>::setPair(Key key, Value value)
{ // error here
pairKey = key;
pairValue = value;
}
template<typename Key,typename Value>
Key KeyValuePair<Key,Value>::getKey() const
{ // error here
return pairKey;
}
template<typename Key,typename Value>
Value KeyValuePair<Key,Value>::getValue() const
{ // error here
return pairValue;
}
标题文件:
#ifndef _KEYVALUEPAIR_H_
#define _KEYVALUEPAIR_H_
template<typename Key,typename Value>
class KeyValuePair
{
private:
Key pairKey;
Value pairValue;
public:
KeyValuePair();
void setPair(Key key,Value value);
Key getKey() const;
Value getValue() const;
};
#include "KeyValuePair.cpp"
#endif
答案 0 :(得分:2)
现在,您的KeyValuePair.h文件底部有一个#include KeyValuePair.cpp
。 KeyValuePair.cpp也#include头文件。头文件具有通常的“防护”(#ifndef _KEYVALUEPAIR_H_),以防止被包含多次,但您的CPP文件不会。因此,当您尝试编译CPP文件时,它会拉入H文件,该文件会再次提取CPP文件。因此,多重定义错误。
最简单的解决方案,但不一定是最正确的解决方案,是从KeyValueHeader.cpp文件的顶部删除#include "KeyValuePair.h"
行。
我怀疑你是在尝试在你的Makefile中实际编译KeyValuePair.cpp,你不需要(也不应该)这样做。您只需要将需要模板类的源文件发送到#include "KeyValuePair.h"
。
模板的标准做法是将声明和实现保持在同一个头文件中 - 这隐含地避免了这些问题。在模板类声明中内嵌模板类方法的实现并且所有实例都包含在单个头文件中并不罕见。破坏您从接口与实现分离所学到的一切,但更容易使用。
答案 1 :(得分:1)
您需要将模板的所有代码放入头文件中,因为它们是按需编译的。
请参阅templates文档。