我试图为我的所有实验室工作整理一个“框架”,但后来我遇到了令人沮丧的链接器错误,处理纯虚函数的实现..
当我从.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&gt; Stack_Array.h:
#include "FrameWork.h"
#include<iostream>
using namespace std;
template <class T>
class Stack_Array : public labTest
{
public:
virtual void execute();
};
======================================
3&gt; 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&gt; 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)" (?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 =======================
如果我制作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 !!";
}
};
我确信这有些愚蠢的事情......我忽略了什么吗?......但我仍然需要帮助......
提前致谢...
答案 0 :(得分:3)
模板的定义必须在使用它的所有翻译单元中可用(除非涉及显式的特化/实例化,否则这不是这种情况)。换句话说,必须在头文件中定义类模板的成员函数。
答案 1 :(得分:2)
void Stack_Array<T>::execute(void)
仅在定义它的编译单元中定义。在Stack_Array.cpp之外,您的编译器不知道如何在execute
上实现Stack_Array<T>
。通常,模板实例化请求不会从一个执行单元传递到另一个执行单元。现在,您可以通过将Stack_Array<T>
的实现放入头文件中,或者通过显式实例化<T>
中要导出的Stack_Array.cpp
来解决此问题。
C ++已尝试添加对交叉编译单元导出和模板实例化请求的支持,但这很棘手。
最简单的解决方案是将您的实现移动到头文件中,并确保这些方法是内联的(或者在类的主体中)。