2010-06-28 109 views
3

亲爱的所有人,我一直坚持这个问题几天,我的搜索没有成功。了解C++中的模板类 - 新运算符的问题

我在做什么: 我想要一个模板阅读器类(VariableReader)来处理不同类型的变量(通常是unsigned int和指向vector的指针)。

我开始与

#ifndef READER_H_ 
#define READER_H_ 
#include <string> 

namespace BAT { 
template <typename variableType = unsigned int> 
class VariableReader { 
public: 
VariableReader<variableType>(); 
VariableReader<variableType>(std::string varName); 
virtual ~VariableReader<variableType>(); 
std::string getVariableName(); 
void setVariableName(std::string varName); 
bool isValidVariableName(std::string varName); 
variableType getVariable(); 
private: 
std::string variableName; 
variableType variable; 

}; 

} 

#endif 

#include "../../interface/Readers/VariableReader.h" 

namespace BAT { 

template<typename variableType> 
VariableReader<variableType>::VariableReader() : 
variableName("") { 
// TODO Auto-generated constructor stub 
} 

template <typename variableType> 
VariableReader<variableType>::VariableReader(std::string varName) : 
variableName(varName) { 

} 

template <typename variableType> 
std::string VariableReader<variableType>::getVariableName() { 
return variableName; 
} 

template <typename variableType> 
void VariableReader<variableType>::setVariableName(std::string varName) { 
if (VariableReader::isValidVariableName(varName)) { 
    variableName = varName; 
} 
} 

template <typename variableType> 
bool VariableReader<variableType>::isValidVariableName(std::string varName) { 
return varName != ""; 
} 

template <typename variableType> 
VariableReader<variableType>::~VariableReader() { 
// TODO Auto-generated destructor stub 
} 

} 

然而,尽管它看起来编译我不能等项目中使用它。 编辑:忘了张贴测试代码:

#include "cute.h" 
#include "ide_listener.h" 
#include "cute_runner.h" 

#include "Readers/VariableReader.h" 
using namespace BAT; 

static VariableReader<int> *reader; 

void setUp(){ 
reader = new VariableReader<int>::VariableReader();//this is problem-line 
} 

void thisIsATest() { 
    ASSERTM("start writing tests", false); 
} 

void runSuite(){ 
    cute::suite s; 
    //TODO add your test here 
    s.push_back(CUTE(thisIsATest)); 
    cute::ide_listener lis; 
    cute::makeRunner(lis)(s, "The Suite"); 
} 

int main(){ 
    runSuite(); 
} 

我获得以下错误信息:

Building target: BAT_Tests 
Invoking: GCC C++ Linker 
g++ -L"/workspace/BAT/Debug Gcov" -fprofile-arcs -ftest-coverage -std=c99 -o"BAT_Tests" ./src/Test.o -lBAT 
./src/Test.o: In function `setUp()': 
/workspace/BAT_Tests/Debug Gcov/../src/Test.cpp:13: undefined reference to `BAT::VariableReader<int>::VariableReader()' 
collect2: ld returned 1 exit status 
make: *** [BAT_Tests] Error 1 

据我所知,链接器会尝试找到VariableReader的构造,这是不明确的,因为定义我只想要一个通用的构造函数。

请帮我理解我缺少的东西。

+0

为什么你明确地调用构造函数? 'reader = new VariableReader ();'应该足够了 – DaClown 2010-06-28 10:57:34

+0

这给了我和以前一样的链接器问题。 – DragonTux 2010-06-28 13:02:26

回答

6

的C++ FAQ精简版部分显示两个解决方案:

  1. 移动模板类的方法到.h文件(或由.h文件中包含的文件)。
  2. 使用template VariableReader<unsigned int>;实例化.cpp文件中的模板。
+0

感谢您的链接,它帮助我了解更多。 我已经在C++文件中实例化了模板。但是,这对我来说似乎是模板概念的一个缺点。为什么我应该为每种类型定义一个模板? 无论如何它现在的作品,我会尝试以后1号。 Thx – DragonTux 2010-06-28 12:49:28

+0

@Golden:你说得对,这是模板的缺点。通过使其仅用于标题,您可以避免需要明确指定它的工作类型,以便随时随地在您的类中使用更多的代码。但99%的时间,这是更有用的选择。 – 2010-06-28 14:03:14

3

构造函数和析构函数不需要模板参数。另外,模板类必须具有完整的源代码才能编译 - 您不能像使用普通类一样声明成员并在另一个翻译单元中定义它们。在How can I avoid linker errors with my template functions?

+0

这通常意味着您需要头文件中的实现。 – DanDan 2010-06-28 10:59:15

+0

从c'tor和d'tor中删除模板参数用于编译,但不适用于链接。我仍然必须把 模板VariableReader :: VariableReader(); .cpp文件中的 。 似乎没有什么像模板一样,因为我喜欢它。 基本上我想要的是一个类需要一个模板来创建一个私有变量: VariableReader * intReader = new VariableReader(); VariableReader *> * floatReader = new VariableReader(); int var = intReader-> getVariable(); vector * var2 = intReader-> getVariable(); – DragonTux 2010-06-28 12:58:22