c++模板类的使用,编译的问题

前两天在写代码时,把模板类的声明和分开放在两个文件中了,类似于下面这样:

stack.hpp:

#ifndef _STACK_HPP
#define _STACK_HPP

template
class stack {
    public:
            stack();
            ~stack();
};
#endif

stack.cpp:

#include <iostream>
#include "stack.hpp"

template <typename type> stack<type>::stack() {
        std::cerr << "Hello, stack " << this << "!" << std::endl;
}

template <typename type> stack<type>::~stack() {
        std::cerr << "Goodbye, stack " << this << "." << std::endl;
}
</type></typename></type></typename></iostream>

main.cpp

#include "stack.hpp"

int main() {
    stack s;

    return 0;
}
$ g++ -c -o main.o main.cpp
$ g++ -c -o stack.o stack.cpp
$ g++ -o main main.o stack.o
main.o: In function `main':
main.cpp:(.text+0xe): undefined reference to 'stack::stack()'
main.cpp:(.text+0x1c): undefined reference to 'stack::~stack()'
collect2: ld returned 1 exit status
make: *** [program] Error 1

提示找不到函数的定义

在网上寻找的答案如下:

It is not possible to write the implementation of a template class in a separate cpp file and compile. All the ways to do so, if anyone claims, are workarounds to mimic the usage of separate cpp file but practically if you intend to write a template class library and distribute it with header and lib files to hide the implementation, it is simply not possible.

To know why, let us look at the compilation process. The header files are never compiled. They are only preprocessed. The preprocessed code is then clubbed with the cpp file which is actually compiled. Now if the compiler has to generate the appropriate memory layout for the object it needs to know the data type of the template class.

Actually it must be understood that template class is not a class at all but a template for a class the declaration and definition of which is generated by the compiler at compile time after getting the information of the data type from the argument. As long as the memory layout cannot be created, the instructions for the method definition cannot be generated. Remember the first argument of the class method is the ‘this’ operator. All class methods are converted into individual methods with name mangling and the first parameter as the object which it operates on. The ‘this’ argument is which actually tells about size of the object which incase of template class is unavailable for the compiler unless the user instantiates the object with a valid type argument. In this case if you put the method definitions in a separate cpp file and try to compile it the object file itself will not be generated with the class information. The compilation will not fail, it would generate the object file but it won’t generate any code for the template class in the object file. This is the reason why the linker is unable to find the symbols in the object files and the build fails.

Now what is the alternative to hide important implementation details? As we all know the main objective behind separating interface from implementation is hiding implementation details in binary form. This is where you must separate the data structures and algorithms. Your template classes must represent only data structures not the algorithms. This enables you to hide more valuable implementation details in separate non-templatized class libraries, the classes inside which would work on the template classes or just use them to hold data. The template class would actually contain less code to assign, get and set data. Rest of the work would be done by the algorithm classes.

具体原因就是:

模板类其实就不是一个类,c++的编译器在编译.cpp产生二进制目标文件的时候,需要根据函数的参数类型来确定链接符号(编译器不编译.h文件),而编译模板类的时候因为函数的参数类型都没有确定,所以也就不能产生链接符号,所以在编译阶段是不会报错的,但是在链接阶段就报错了。针对这种情况有三种解决办法,但是最优的还是把实现和声明都放在头文件中。如果不想让c++类显得臃肿,可以在类里面声明,在类外进行实现。

参考链接

Original: https://www.cnblogs.com/xutopia/p/15715756.html
Author: xutopia
Title: c++模板类的使用,编译的问题

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/611220/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 双绞线

    双绞线简介 双绞线(twisted pair,TP)是一种综合布线工程中最常用的传输介质,双绞线一般由两根22~26号绝缘铜导线相互缠绕而成,在一个电缆套管里的,不同线对具有不同的…

    Linux 2023年6月7日
    073
  • Unable to install NuGet provider for PowerShell

    https://docs.microsoft.com/en-us/officeonlineserver/enable-tls-1-1-and-tls-1-2-support-in-…

    Linux 2023年5月28日
    064
  • CentOS 7安装jdk-mysql-nginx

    安装jdk 设置开机自启 重启systemctl Original: https://www.cnblogs.com/nianxue/p/16618805.htmlAuthor: …

    Linux 2023年6月6日
    068
  • date 参数(option)-d

    记录这篇博客的原因是:鸟哥的linux教程中,关于date命令的部分缺少-d这个参数的介绍,并且12章中的shell编写部分有用到-d参数 date 参数(option)-d与&#…

    Linux 2023年6月6日
    089
  • MVC(二)

    通过前一篇文章,我们对MVC有了一定的了解。 三、MVC能做什么 网站——服务器返回页面——实际上就是一段文本(response header+html)。 实际上mvc的acti…

    Linux 2023年6月13日
    0104
  • docker 安装redis

    1、获取 redis 镜像 2、查看本地镜像 bind 127.0.0.1 #注释掉这部分,这是限制redis只能本地访问 protected-mode no #默认yes,开启保…

    Linux 2023年5月28日
    085
  • Git的使用以及常用命令(详解)

    一、 版本控制工具 什么是版本控制系统? 版本控制系统(Version Control System):是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。版本控…

    Linux 2023年6月6日
    0102
  • Redis6 源码调式

    Redis6 源码调式 安装Cygwin 1、下载安装Cygwin 去Cygwin的官方网站http://www.cygwin.com/ window 64位请选择 setup-x…

    Linux 2023年5月28日
    0122
  • 【实操填坑】在树莓派上编译 EtherCAT IgH Master 主站程序

    官网下载地址:https://etherlab.org/download/ethercat/ (可list查看文件列表)https://etherlab.org/download/…

    Linux 2023年6月7日
    0120
  • 6.22(js–>案例应用)

    (练习1)简易计算器: <html lang="en"> <head> <meta charset="UTF-8&quo…

    Linux 2023年6月7日
    0105
  • 使用 Active Directory PowerShell 模块收集 AD 数据

    原文:https://adsecurity.org/?p=3719 chrome默认翻译结果 Microsoft 随 Windows Server 2008 R2(和更新版本)提供…

    Linux 2023年5月28日
    087
  • Mysql实战技能全解

    一、数据库原理 1 数据的分类 结构化的数据:即有固定格式和有限长度的数据。例如填的表格就是结构化的数据,国籍:中华人民共和国,民族:汉,性别:男,这都叫结构化数据 非结构化的数据…

    Linux 2023年6月7日
    0134
  • 面试复盘(1)

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年6月7日
    094
  • Nginx基础入门篇(1)—优势及安装

    一、Nginx 的优势 1.1发展趋势: 2016年: 1.2、简介 Nginx (engine x) 是一个高性能的HTTP(解决C10k的问题)和反向代理服务器,也是一个IMA…

    Linux 2023年6月6日
    090
  • Xbox无法进入开发者模式

    从2020.09.01起,Xbox的dev mode app估计是证书过期或者其他系统配置问题,导致大量开发者无法进入开发者模式,具体如下图所示。 针对上述问题,可以通过微软预先设…

    Linux 2023年6月13日
    0237
  • Linux专项之Apache

    1.&#x865A;&#x62DF;&#x673A;&#x4E0A;&#x7F51; 1.安装软件(httpd) yum search ht…

    Linux 2023年5月27日
    086
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球