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...

2 Answers 2

3

A definition of a template must be available in all translation units in which it is used (unless explicit specialisation/instantiation is involved, which is not the case here). In other words, member functions of class templates must be defined in header files.

Sign up to request clarification or add additional context in comments.

Comments

2

void Stack_Array<T>::execute(void) is only defined within the compilation unit where it is defined. Outside of Stack_Array.cpp, your compiler has no idea how to implement execute on Stack_Array<T>. In general, template instantiation requests are not passed from one execution unit to another. Now, you can fix this by either putting the implementation of Stack_Array<T> into header files, or by explicitly instantiating the <T> that you want to export in Stack_Array.cpp.

C++ has tried to add support for cross-compilation-unit exporting and requesting of template instantiations, but it is tricky.

The easiest solution is to move your implementation into a header file, and make sure the methods are inline (or in the body of the class).

1 Comment

Thanks for clearing this. This behavior of c++ was a bit of a surprise to me. And I did not see many discussing this problem out there in forums or such.... thanks ny way. I ll take my code into the header...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.