2012-11-20 36 views
3

我試圖放在一起爲我所有的實驗室作品「框架」,但後來我跑進處理純虛函數的實現一個令人沮喪的鏈接錯誤..從.h和.cpp文件定義純虛函數會導致鏈接器錯誤?

當我從一個定義純虛函數.cpp文件(如returntype classname :: function(){.....})我得到一個鏈接器錯誤,告訴我純虛函數的定義不提供...

但是,當我簡單地把定義的頭文件,它工作得很好。我知道我的聲音混亂...但下面的代碼一定會幫助你看到發生了什麼..

誰能幫我ü理解爲什麼會發生這種情況?

項目包含4個文件,(2個標頭,和2個cpp文件)

1> FrameWork.h:

#ifndef _FRAMEWORK 
#define _FRAMEWORK 

#include<iostream> 

class labTest 

{ 
    public : 
     virtual void execute() = 0; 
}; 
#endif 

============== ========================

2> Stack_Array.h:

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

template <class T> 
class Stack_Array : public labTest 
    { 

     public: 
     virtual void execute(); 
    }; 

========= =============================

3> Stack_Array.cpp:

#include "Stack_Array.h" 
template<class T> 

virtual void Stack_Array<T>::execute(void) // I beleive i am defining the pure virtual function here, but my compiler ll not agree. 
    { 
     std::cout << "Test"; 
    } 

================================= =====

4> Main_Run.cpp:

#include<istream> 
#include"FrameWork.h" 
#include"Stack_Array.h" 
#include<vector> 
using namespace std; 

void main() 
    { 
    vector<labTest*> list(5); 
    vector<labTest*>::iterator it; 
    it = list.begin(); 
    Stack_Array<int>* sa = new Stack_Array<int>(); 

    list.insert(it,sa); 
    list[0]->execute(); 
    getchar(); 

    } 

============================ =============

生成輸出:

1>------ Rebuild All started: Project: Lab FrameWork, Configuration: Debug Win32 ------ 
1>Build started 11/20/2012 6:16:48 PM. 
1>InitializeBuildStatus: 
1> Touching "Debug\Lab FrameWork.unsuccessfulbuild". 
1>ClCompile: 
1> Stack_Array.cpp 
1> Main_Run.cpp 
1> Generating Code... 
1>Main_Run.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Stack_Array<int>::execute(void)" ([email protected][email protected]@@UAEXXZ) 
1>C:\Users\BSP-4\Documents\Visual Studio 2010\Projects\SFML\Lab FrameWork\Debug\Lab FrameWork.exe : fatal error LNK1120: 1 unresolved externals 
1> 
1>Build FAILED. 
1> 
1>Time Elapsed 00:00:01.64 

========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ======================= 

它的工作原理,如果我做我的Stack_Array.h:

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

template <class T> 
class Stack_Array : public labTest 
{ 

    public: 
    void execute() // give the definition here instead of Stack_Array.cpp and it will work ! 
     { 
      cout << "Test Success !!"; 
     } 
}; 

我相信它的一些愚蠢的事情..難道我忽略的東西..但我仍然需要幫助....

在此先感謝...

回答

2

void Stack_Array<T>::execute(void)僅在定義它的編譯單元中定義。 Stack_Array.cpp之外,你的編譯器不知道如何在Stack_Array<T>實施execute。通常,模板實例化請求不會從一個執行單元傳遞到另一個執行單元。現在,你可以通過外放Stack_Array<T>落實到頭文件,或通過顯式實例化要在Stack_Array.cpp出口<T>解決這個問題。

C++試圖增加對交叉編譯單元出口和請求模板實例的支持,但它是棘手的。

最簡單的解決方法是你實現移動到一個頭文件,並確保該方法是行內(或在類的主體)。

+0

感謝您的清除。 C++的這種行爲讓我感到有點意外。我沒有看到很多討論這個問題在那裏論壇或這樣的....謝謝你的方式。我將把我的代碼放入標題中... –

3

模板的定義必須在所有使用該模板的翻譯單元中可用(除非涉及明確的專門化/實例化,這裏不是這種情況)。換句話說,類模板的成員函數必須在頭文件中定義。

+0

感謝您清除此... –