2012-09-03 45 views
2

Possible Duplicate:
C++ template, linking errorLNK2019在C++

鏈接錯誤我有兩個鏈接錯誤,我不知道什麼是錯的代碼,以及如何解決這些問題:

main.obj:-1: error: LNK2019: unresolved external symbol "public: __thiscall A::A(void)" ([email protected]@@@@[email protected]) referenced in function "public: __thiscall B::B(void)" ([email protected]@[email protected])

main.obj:-1: error: LNK2019: unresolved external symbol "public: void __thiscall A::exec(void (__thiscall B::*)(void))" ([email protected][email protected]@@@@[email protected]@[email protected]) referenced in function "public: void __thiscall B::run(void)" ([email protected]@@QAEXXZ)

解釋代碼有點: 這個類必須從派生類中執行一個函數。函數exec通過派生類中的函數從派生類中調用。此函數的簽名是void function();

//header.h

#ifndef HEADER_H 
#define HEADER_H 

template <class T> 
class A 
{ 
public: 
    typedef void (T::*ExtFunc)(); 

    A(); 
    void funcA(); 
    void exec(ExtFunc func); 
}; 

#endif // HEADER_H 

//header.cpp

#include "header.h" 

template<typename T> 
A<T>::A() { } 

template<typename T> 
void A<T>::funcA() 
{ 
    cout << "testA\n"; 
} 

template<typename T> 
void A<T>::exec(ExtFunc func) 
{ 
    (T().*func)(); 
} 

main.cpp我從A類派生類,並通過派生類作爲模板paramtere。然後通過run()函數執行功能exec。 //main.cpp

#include <iostream> 
#include "header.h" 
using namespace std; 

class B : public A<B> 
{ 
public: 
    B() { } 

    void run() 
    { 
     exec(&B::funcB); 
    } 

    void funcB() 
    { 
     cout << "testB\n"; 
    } 
}; 

int main() 
{ 
    B ob; 
    ob.run(); 

    return 0; 
} 

誰能告訴我這是怎麼回事...

回答

2

當您使用的模板,通常你不能把實施.cpp文件 - 你必須把標題中的整個班級。因此,將所有代碼從header.cpp移到.h。

您可以通過在.cpp文件中執行顯式實例來解決此問題 - 爲特定類型實例化模板。但是這要求您提前知道哪些類型需要實例化,並且會阻止您添加新的實例化。唯一的好處是減少了編譯時間。

+0

另一種可能的'hack'是_頭文件_中的源文件。 – Hindol

+0

謝謝你的答案。我在網上做了一些搜索,看看之前的代碼有什麼問題,並且我發現了你剛剛說的。但在cplusplus.com論壇上,我發現一個人說這是可能的。問題是我沒有弄清楚如何從他評論的內容中做到這一點。 http://www.cplusplus.com/forum/general/14162/#msg69074 這是'guestgulkan(2668)' –

+0

@JohnSmith的第一個評論,這就是我認真回答的原因:)。如果您在.cpp文件中明確地實例化模板,它實際上會創建該類型,因此鏈接器將可用。但這樣做的主要原因是爲了減少編譯時間,所以在大多數情況下,您應該簡單地將實現保留在頭文件中。 –