2010-06-28 105 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