简体   繁体   English

从.h和.cpp文件定义纯虚函数会产生链接器错误?

[英]Defining pure virtual functions from .h and .cpp files yields linker error?

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... 当我从.cpp文件定义纯虚函数时(如returntype classname :: function(){.....})我得到一个链接器错误,告诉我没有提供纯虚函数的定义.. 。

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) 该项目包含4个文件,(2个标题和2个cpp文件)

1 > FrameWork.h : 1> FrameWork.h:

 #ifndef _FRAMEWORK
 #define _FRAMEWORK

 #include<iostream>

 class labTest

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

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

2 >Stack_Array.h : 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 : 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 : 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 : 如果我创建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... 提前致谢...

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. 换句话说,必须在头文件中定义类模板的成员函数。

void Stack_Array<T>::execute(void) is only defined within the compilation unit where it is defined. void Stack_Array<T>::execute(void)仅在定义它的编译单元中定义。 Outside of Stack_Array.cpp, your compiler has no idea how to implement execute on Stack_Array<T> . 在Stack_Array.cpp之外,您的编译器不知道如何在Stack_Array<T>上实现execute 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 . 现在,您可以通过将Stack_Array<T>的实现放入头文件中,或者通过显式实例化要在Stack_Array.cpp导出的<T>Stack_Array.cpp

C++ has tried to add support for cross-compilation-unit exporting and requesting of template instantiations, but it is tricky. C ++试图添加对交叉编译单元导出和模板实例化请求的支持,但它很棘手。

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). 最简单的解决方案是将您的实现移动到头文件中,并确保方法是内联的(或在类的主体中)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM