问题场景:
在做《剑指offer》的面试题7:用两个栈实现一个队列,作者给出的代码只有两个文件,一个头文件和一个cpp源文件,然而从程序设计的角度来看,应当将头文件中的声明留在头文件中,函数的实现应当写在cpp源文件中,写完代码后,运行然而出现了问题。
问题描述
让我百思不得其解的是,我按照《c++ primer plus》书中写的代码,也采用声明和实现在不同文件中的方式,完全正确。而我对比两者的代码,除了实现功能不同外,逻辑思维皆是一致的。故令我无法理解其中的原因。
代码语言和编译环境:
c++代码,Windows下编译器vs2017
出现的问题:
1>usestock0.obj : error LNK2019: 无法解析的外部符号 “public: __thiscall CQueue::CQueue(void)” (??0?
KaTeX parse error: Expected group after ‘_’ at position 89: …的外部符号 “public: _̲_thiscall CQueu…
CQueue@D@@QAE@XZ),该符号在函数 _main 中被引用
1>usestock0.obj : error LNK2019: 无法解析的外部符号 “public: void __thiscall CQueue::appendTail(char const &)” (?appendTail@?
KaTeX parse error: Expected group after ‘_’ at position 97: … “public: char _̲_thiscall CQueu…
CQueue@D@@QAEDXZ),该符号在函数 _main 中被引用
//头文件
#pragma once
#include <stack>
#include <exception>
using namespace std;
template <typename T> class CQueue
{
public:
CQueue(void);
~CQueue(void);
void appendTail(const T& node);
T deleteHead();
private:
stack<T> stack1;
stack<T> stack2;
};
//头文件中函数实现文件
#include "queue.h"
using namespace std;
template <typename T> CQueue<T>::CQueue(void) {}
template <typename T> CQueue<T>::~CQueue(void) {}
template <typename T> void CQueue<T>::appendTail(const T& element)
{
stack1.push(element);
}
template <typename T> T CQueue<T>::deleteHead()
{
if (stack2.size() <= 0)
{
while (stack1.size() > 0)
{
T& data = stack1.top();
stack1.pop();
stack2.push(data);
}
}
if (stack2.size() == 0)
{
throw new exception("queue is empty");
}
T head = stack2.top();
stack2.pop();
return head;
}
//主函数文件
#include "queue.h"
void Test(char actual, char expected)
{
if (actual == expected)
printf("Test passed.\n");
else
printf("Test failed.\n");
}
int main(int argc, char* argv[])
{
CQueue<char> queue;
queue.appendTail('a');
queue.appendTail('b');
queue.appendTail('c');
char head = queue.deleteHead();
Test(head, 'a');
head = queue.deleteHead();
Test(head, 'b');
queue.appendTail('d');
head = queue.deleteHead();
Test(head, 'c');
queue.appendTail('e');
head = queue.deleteHead();
Test(head, 'd');
head = queue.deleteHead();
Test(head, 'e');
return 0;
}
原因分析:
queue.cpp中实现的函数,在主函数cpp文件中被引用,但是无法找到内容
解决方案:
在网上搜了好多好多方案,但是无一例外,全部无法解决问题。网上的解决方案大多都提出了程序设计时工程文件应当在同一个项目中的问题,有些方案提出文件编译问题,然而,我的文件都在同一项目下,因为是简单代码,是全部写完以后一起编译运行,所以应当也不会因为文件的编译问题出错。
唯一可行的解决办法就是:在主函数源文件中,采用 #include “queue.cpp” 的方式引入函数实现文件。至今为止,笔者并无其他办法,也并未探索其中的根本原因。或许,这就是一开始学习计算机专业就采用集成IDE工具的恶果,对底层编译和运作不了解。
如果您对这一问题有解决办法或者了解原因,欢迎您和我进行交流。
//改正后的代码
#include "queue.h"
#include "queue.cpp"
void Test(char actual, char expected)
{
if (actual == expected)
printf("Test passed.\n");
else
printf("Test failed.\n");
}
int main(int argc, char* argv[])
{
CQueue<char> queue;
queue.appendTail('a');
queue.appendTail('b');
queue.appendTail('c');
char head = queue.deleteHead();
Test(head, 'a');
head = queue.deleteHead();
Test(head, 'b');
queue.appendTail('d');
head = queue.deleteHead();
Test(head, 'c');
queue.appendTail('e');
head = queue.deleteHead();
Test(head, 'd');
head = queue.deleteHead();
Test(head, 'e');
return 0;
}