问题描述
之前写c语言,习惯了将声明和定义分开存放在不同的文件中,其中,声明放在头文件中,定义放在cpp文件中,这样一来方便后期维护,也算是一种规范,众所周知,c语言里面是没有模版这个概念的;直到最近接触了C++;发现在写模版类的时候,将声明和定义分开了,编译死活过不去;以下是代码
BlockQueue.h
#ifndef TEST_BLOCKQUEUE_H
#define TEST_BLOCKQUEUE_H
template <class E>
class BlockQueue {
public:
void show();
};
#endif //TEST_BLOCKQUEUE_H
BlockQueue.cpp
#include "../include/BlockQueue.h"
template<class E>
void BlockQueue<E>::show() {
}
main.cpp
#include <iostream>
#include "include/BlockQueue.h"
int main() {
auto *pQueue = new BlockQueue<int>();
pQueue->show();
std::cout << "Hello, World!" << std::endl;
return 0;
}
编译
每次编译都报错: undefined reference to 'BlockQueue<int>::show()'
,不管在手动命名行编译还是用idea都一样
root@yexindong:/tmp/tmp.rgBT7teaPz# g++ main.cpp src/BlockQueue.cpp -o m2
/usr/bin/ld: /tmp/ccRV0afS.o: in function `main':
main.cpp:(.text+0x22): undefined reference to `BlockQueue<int>::show()'
collect2: error: ld returned 1 exit status
以下的Clion idea的报错
解决
很明显,如果按照普通函数一样,将模板函数的声明与定义的分开,声明放在头文件,定义放在cpp文件实现,你会发现,编译没问题,但是在链接阶段会报”undefined references“。
解决方法也很简单,就是将cpp文件BlockQueue.cpp
删掉即可,,然后将声明和定义都放在头文件即可;
BlockQueue.h 文件修改为以下内容:
#ifndef TEST_BLOCKQUEUE_H
#define TEST_BLOCKQUEUE_H
template <class E>
class BlockQueue {
public:
void show();//声明
};
// 定义
template<class E>
void BlockQueue<E>::show() {
}
#endif //TEST_BLOCKQUEUE_H
再次运行main函数就可以通过了;