C++模板类编程的链接问题
来源:互联网 发布:macos不支持windows 编辑:程序博客网 时间:2024/06/06 08:51
问题引入
前两天想写一个模板类,里面放一些编程的时候常用的函数,比如动态创建二维数组。下面是我一开始写的代码:
//templateLibrary.h #include <exception> template <class T>class arrayCommand { public: arrayCommand(); ~arrayCommand(); //二维数组构造 bool make2dArray(T** &x, const int & numberOfRows, const int & numberOfColumns); private: };--------------------------------------------//templateLibrary.cpp#include "stdafx.h"#include "templateLibrary.h"#include <iostream>template <class T>arrayCommand<T>::arrayCommand() {}template <class T>arrayCommand<T>::~arrayCommand() {}//二维数组构造template <class T>bool arrayCommand<T>::make2dArray(T** &x, const int & numberOfRows, const int & numberOfColumns) {// Create a two dimensional array. try { // create pointers for the rows x = new T *[numberOfRows]; // get memory for each row for (int i = 0; i < numberOfRows; i++) x[i] = new int[numberOfColumns]; return true; } catch (std::bad_alloc) { return false; } }------------------------------------------------//test.cpp#include "templateLibrary.h"#include <iostream>int main(){ int** a; arrayCommand<int> *arrCommand = new arrayCommand<int>; arrCommand->make2dArray(a, 2, 2); a[0][0] = 1; a[0][1] = 2; a[1][0] = 3; a[1][1] = 4; std::cout << a[0][0] << ' ' << a[0][1] << std::endl; std::cout << a[0][0] << ' ' << a[1][1] << std::endl; system("pause>>null"); return 0;}
这段代码是不能够正确运行的,编译器会报出一个符号在main函数中被引用的错误。
使用gdb逐语句进行调试,一开始就会报错,可以判定这段代码实在程序运行之前有问题,在网上查阅了error LNK2019,发现是链接的问题。
为解决这个问题,就要深入的理解模板实例化。
问题分析
C++中模板的实例化指函数模板(类模板)生成模板函数(模板类)的过程。对于函数模板而言,模板实例化之后,会生成一个真正的函数。而类模板经过实例化之后,只是完成了类的定义,模板类的成员函数需要到调用时才会被初始化。
在上面的例子中,arrayCommand是一个模板,但是并不是一个类型,而arrayCommand<int>是一个模板实例,是一个类型。所以,从arrayCommand 创建arrayCommand<int>实例的过程就是模板的实例化过程。
首先,在编译阶段,编译器需要创建一个arrayCommand<int>类型,当编译器编译templateLibrary.cpp的时候,因为不知道模板arrayCommand 的参数,故不能生成模板类的成员函数的代码;当编译器编译templateLibrary.h的时候,明确了模板arrayCommand 的声明,但是在此文件中没有找到模板的定义,所以在编译阶段不能够生成类型arrayCommand<int>,但是此时并不会报错,因为编译器可能认为类型arrayCommand<int>的定义在其它的文件中,所以就交给之后的链接程序处理。
在链接阶段,我们需要找到arrayCommand<int>的定义,但是在编译阶段并没有生成成员函数的代码,所以,找不到相应的定义,就会报出上述的错误。
问题解决
分析过问题的原因之后,这个问题就迎刃而解了,我们知道在编译阶段编译器在templateLibrary.h中找不到arrayCommand<int>的定义,所以只要将templateLibrary.cpp中的内容添加至在templateLibrary.h中即可。
经验证,这种方法可以解决此问题。
注:本篇博客部分参考了http://blog.csdn.net/onafioo/article/details/29857281,原博客中作者给出了另外的解决方法。
- C++模板类编程的链接问题
- C++primer学习:模板编程(2):类模板的定义
- 模板类的小问题(链接失败)
- C++ 模板类的静态成员变量链接问题
- 关于C++模板的链接错误问题
- 链接指示: extern "C" C和C++混合编程问题
- C的xml编程文章链接
- 类模板最常见的链接错误
- C/C++链接有关的问题
- C#:异步时的链接跳转问题
- [C++]模板类的声明与实现分离问题
- 模板元编程的循环问题
- 类模板与友元函数链接问题
- 动态链接库导出模板类以及一些问题
- linux C编程入门之静态链接库、动态链接库的编译与链接
- c语言链接问题
- C++学习笔记6--高级强制类型转换 命名空间和模块化编程 C预处理器 链接和作用域 函数模板 类模板 内联模板 容器和算法
- 介绍几个学习C语言编程的链接
- JQuery中$.ajax()方法参数详解
- 适配器模式
- EventBus源码阅读(12)-PendingPostQueue
- 《WebApi》----将异常堆栈信息写入日志文件
- Intellj idea 15中创建Maven多模块
- C++模板类编程的链接问题
- next_permutation函数
- .NET平台开源文档与报表处理组件
- luaj
- 《Android 开发工程师面试指南》
- MAPENTRY
- Qt5-控件-QMenu,QMenuBar-菜单栏详解-菜单热键-菜单校验功能
- Oracle序列和主键映射
- java中AJAX使用JSON的实例