3

I was trying to put together a 'framework' for all my lab works, but then I ran into a frustrating linker error dealing with the implementation of pure virtual function..

When I define the pure virtual function from a .cpp file ( like returntype classname::function() {.....} ) I get a linker error, telling me that the definition of the pure virtual function is not provided...

However, when i simply put the definition to the header file, it works well.. I know i sound confusing... but the code below will surely help you see what is happening..

Can anyone please help me understand why is this happening ?

The project contains 4 files, ( 2 headers, and 2 cpp files)

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();

  }

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

Build Output :

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)" (?execute@?$Stack_Array@H@@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 =======================

It works if I make my 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 !!";
       }
};

I am sure its some silly thing.. Did I overlooked something ?.. but am still in need of help....

Thanks in advance...

4

2 に答える 2

3

テンプレートの定義は、それが使用されるすべての翻訳単位で使用可能である必要があります(明示的な特殊化/インスタンス化が含まれている場合を除き、ここではそうではありません)。つまり、クラステンプレートのメンバー関数はヘッダーファイルで定義する必要があります。

于 2012-11-20T13:50:21.873 に答える
2

void Stack_Array<T>::execute(void)定義されているコンパイルユニット内でのみ定義されます。Stack_Array.cppの外部では、コンパイラはに実装する方法がわかりませexecuteStack_Array<T>。一般に、テンプレートのインスタンス化要求は、ある実行ユニットから別の実行ユニットに渡されません。Stack_Array<T>これで、の実装をヘッダーファイルに入れるか<T>、エクスポートするを明示的にインスタンス化することで、これを修正できますStack_Array.cpp

C ++は、クロスコンパイルユニットのエクスポートとテンプレートのインスタンス化の要求のサポートを追加しようとしましたが、注意が必要です。

最も簡単な解決策は、実装をヘッダーファイルに移動し、メソッドがインライン(またはクラスの本体)にあることを確認することです。

于 2012-11-20T13:49:54.433 に答える