2012-04-24 58 views
3

鏈接錯誤,我需要生成一個簡單的記錄器(用了第三方庫),這是必須鏈接DLL。因此,我生成了一些他的類方法的類是模板,代碼編譯正常,但我得到鏈接器錯誤。我正在編譯MS VS 2008和gcc-4。該代碼是:在C++模板

Log.h類:

class MiniLogger 
{ 
private: 
    std::ofstream mOutPutFile; 
protected: 
    void write (std::string const& text); 
public: 
    ~MiniLogger(); 
    MiniLogger(std::string const& lName) throw(FileError); 
    static MiniLogger* getInstance(std::string const & fName); 
    static void destoryInstance(MiniLogger*); 

    template<class T> 
    MiniLogger& operator<<(T & data); 
    MiniLogger& operator<<(std::ostream& (*func)(std::ostream&)); 

}; 


MiniLogger& MiniLogger::operator<< (std::ostream& (*func)(std::ostream&)) 
{ 

    //mOutPutFile << out; 
    return *this; 
} 
template<class T> 
MiniLogger& MiniLogger::operator<< (T & data) 
{ 
//Just try with out calling other method 
// write(data); 
    return *this; 
} 

在主我實例化對象,並使用它:

#include "log.h" 

int main() 
{ 


    MiniLogger &a=*(MiniLogger::getInstance("text.txt")); 

    a << "text" << std::endl; 


return 0; 
} 

我得到

@ubu11-10-64b-01:~/cplus/template$ g++ main.cpp log.cpp 
/tmp/cccMdSBI.o: In function `MiniLogger::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))': 
log.cpp:(.text+0x0): multiple definition of `MiniLogger::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))' 
/tmp/ccj3dfhR.o:main.cpp:(.text+0x0): first defined here 
+0

請注意,模板代碼工作就好了;你的鏈接器錯誤是在*非* -template代碼。 – 2012-04-24 15:54:43

回答

4

您已經定義頭文件中的函數。由於該頭文件包含在多個翻譯單元(即main.cpp和log.cpp)中,因此您已經多次定義了該函數。 (請參閱One Definition Rule。)

要麼聲明函數inline和在頭文件定義它,或者聲明它在頭文件extern和在一個源文件中定義。

有問題的功能是:MiniLogger& MiniLogger::operator<< (std::ostream& (*func)(std::ostream&))

溶液#1:

// Log.h 
inline 
MiniLogger& MiniLogger::operator<< (std::ostream& (*func)(std::ostream&)) 
{ 
//mOutPutFile << out; 
return *this; 
} 

溶液#2:

// Log.h 
extern 
MiniLogger& MiniLogger::operator<< (std::ostream& (*func)(std::ostream&)); 

// Log.cpp 
MiniLogger& MiniLogger::operator<< (std::ostream& (*func)(std::ostream&)) 
{ 
//mOutPutFile << out; 
return *this; 

} 


旁註:認識到,在頭文件, template<class T> MiniLogger& MiniLogger::operator<< (T & data)下一個實體,不是函數 - 它是一個函數模板 - 不同的建議適用於它。作爲一個經驗法則,你應該 頭文件定義函數模板,但 應該在頭文件中所定義的功能。 (也有例外這一經驗法則。)