记录c++的一个天坑,模版的声明(接口)和定义(实现)必须放一起

发布时间:2023-12-23 21:34:19 作者:yexindonglai@163.com 阅读(814)

问题描述

之前写c语言,习惯了将声明和定义分开存放在不同的文件中,其中,声明放在头文件中,定义放在cpp文件中,这样一来方便后期维护,也算是一种规范,众所周知,c语言里面是没有模版这个概念的;直到最近接触了C++;发现在写模版类的时候,将声明和定义分开了,编译死活过不去;以下是代码

BlockQueue.h

  1. #ifndef TEST_BLOCKQUEUE_H
  2. #define TEST_BLOCKQUEUE_H
  3. template <class E>
  4. class BlockQueue {
  5. public:
  6. void show();
  7. };
  8. #endif //TEST_BLOCKQUEUE_H

BlockQueue.cpp

  1. #include "../include/BlockQueue.h"
  2. template<class E>
  3. void BlockQueue<E>::show() {
  4. }

main.cpp

  1. #include <iostream>
  2. #include "include/BlockQueue.h"
  3. int main() {
  4. auto *pQueue = new BlockQueue<int>();
  5. pQueue->show();
  6. std::cout << "Hello, World!" << std::endl;
  7. return 0;
  8. }

编译

每次编译都报错: undefined reference to 'BlockQueue<int>::show()',不管在手动命名行编译还是用idea都一样

  1. root@yexindong:/tmp/tmp.rgBT7teaPz# g++ main.cpp src/BlockQueue.cpp -o m2
  2. /usr/bin/ld: /tmp/ccRV0afS.o: in function `main':
  3. main.cpp:(.text+0x22): undefined reference to `BlockQueue<int>::show()'
  4. collect2: error: ld returned 1 exit status

以下的Clion idea的报错

解决

很明显,如果按照普通函数一样,将模板函数的声明与定义的分开,声明放在头文件,定义放在cpp文件实现,你会发现,编译没问题,但是在链接阶段会报”undefined references“。

解决方法也很简单,就是将cpp文件BlockQueue.cpp删掉即可,,然后将声明和定义都放在头文件即可;

BlockQueue.h 文件修改为以下内容:

  1. #ifndef TEST_BLOCKQUEUE_H
  2. #define TEST_BLOCKQUEUE_H
  3. template <class E>
  4. class BlockQueue {
  5. public:
  6. void show();//声明
  7. };
  8. // 定义
  9. template<class E>
  10. void BlockQueue<E>::show() {
  11. }
  12. #endif //TEST_BLOCKQUEUE_H

再次运行main函数就可以通过了;

关键字c++