关于C++泛型编程,模板声明和定义最好在同一个文件的解释。
2016-04-07 10:09
495 查看
关于C++泛型编程 模板的 声明和实现 不能分离的原因:
1.泛型-模板 template
2.模板不是变量,模板就是模板。
3.模板需要实例化成类,就像是内联函数进行替换一样,替换模板变量 template<typename T>
4.编译过程
类的编译过程 类 实例化成 对象
模板的编译过程 模板 替换模板变量 特例化成 类 类再实例化成 对象
5.声明 和 定义 分离的 后果
声明 了模板 我们 使用这个模板的时候 会#include"模板.h"
此时编译器 1.会根据我们代入的 模板变量类型 进行替换,但是此时只是替换了 .h头文件里面 的typename T
模板.cpp实现文件 里面的 typename T并没有被替换。
2.开始编译,编译.h并没有错,不过找不到 类实现文件。会在链接link 目标文件的时候 去.cpp编译成.obj的时候 查找 具体实现。
3.由于 模板.cpp里面的 typename T是没有被替换的,没有特例化成类,所以直接报错: 无法解析外部符号,无法解析外部命令。(因为没有类的实现)
例子:
(错误版本)
main.cpp
模板声明
myTemplate.h
myTemplate.cpp
编译结果:
错误 3 error LNK1120: 2 个无法解析的外部命令
F:\VisualStudio2013UltimateProjects\template\Debug\template.exe
template
错误 1 error LNK2019: 无法解析的外部符号 "public: __thiscall myTemplate<int,float>::myTemplate<int,float>(int,float)" (??0?$myTemplate@HM@@QAE@HM@Z),该符号在函数 _main 中被引用
F:\VisualStudio2013UltimateProjects\template\template\template.obj
template
错误 2 error LNK2019: 无法解析的外部符号 "public: int __thiscall myTemplate<int,float>::plus(void)" (?plus@?$myTemplate@HM@@QAEHXZ),该符号在函数 _main 中被引用
F:\VisualStudio2013UltimateProjects\template\template\template.obj
template
(正确版本)
main.cpp
myTempalte.h
运行结果:
24
1.泛型-模板 template
2.模板不是变量,模板就是模板。
3.模板需要实例化成类,就像是内联函数进行替换一样,替换模板变量 template<typename T>
4.编译过程
类的编译过程 类 实例化成 对象
模板的编译过程 模板 替换模板变量 特例化成 类 类再实例化成 对象
5.声明 和 定义 分离的 后果
声明 了模板 我们 使用这个模板的时候 会#include"模板.h"
此时编译器 1.会根据我们代入的 模板变量类型 进行替换,但是此时只是替换了 .h头文件里面 的typename T
模板.cpp实现文件 里面的 typename T并没有被替换。
2.开始编译,编译.h并没有错,不过找不到 类实现文件。会在链接link 目标文件的时候 去.cpp编译成.obj的时候 查找 具体实现。
3.由于 模板.cpp里面的 typename T是没有被替换的,没有特例化成类,所以直接报错: 无法解析外部符号,无法解析外部命令。(因为没有类的实现)
例子:
(错误版本)
main.cpp
#include<iostream> #include"myTemplate.h" using namespace std; int main(int argc, char * argv[]) { myTemplate<int, float> * p = new myTemplate<int, float>(12, 12.0); cout << p->plus()<< endl; cin.get(); }
模板声明
myTemplate.h
#ifndef _MYTEMPLATE_H_ #define _MYTEMPLATE_H_ template<typename T,typename V> class myTemplate{ private: T m_x; V m_y; public: myTemplate(T x, V y); public: T plus(); }; #endif模板实现
myTemplate.cpp
#include"myTemplate.h" template<typename T,typename V> myTemplate<T,V>::myTemplate(T x, V y) { this->m_x = x; this->m_y = y; } template<typename T, typename V> T myTemplate<T,V>::plus() { return (T)(this->m_x + this->m_y); }
编译结果:
错误 3 error LNK1120: 2 个无法解析的外部命令
F:\VisualStudio2013UltimateProjects\template\Debug\template.exe
template
错误 1 error LNK2019: 无法解析的外部符号 "public: __thiscall myTemplate<int,float>::myTemplate<int,float>(int,float)" (??0?$myTemplate@HM@@QAE@HM@Z),该符号在函数 _main 中被引用
F:\VisualStudio2013UltimateProjects\template\template\template.obj
template
错误 2 error LNK2019: 无法解析的外部符号 "public: int __thiscall myTemplate<int,float>::plus(void)" (?plus@?$myTemplate@HM@@QAEHXZ),该符号在函数 _main 中被引用
F:\VisualStudio2013UltimateProjects\template\template\template.obj
template
(正确版本)
main.cpp
#include<iostream> #include"myTemplate.h" using namespace std; int main(int argc, char * argv[]) { myTemplate<int, float> * p = new myTemplate<int, float>(12, 12.0); cout << p->plus()<< endl; cin.get(); }模板声明和实现在同一个文件
myTempalte.h
#ifndef _MYTEMPLATE_H_ #define _MYTEMPLATE_H_ template<typename T,typename V> class myTemplate{ private: T m_x; V m_y; public: myTemplate(T x, V y); public: T plus(); }; template<typename T, typename V> myTemplate<T,V>::myTemplate(T x, V y) { this->m_x = x; this->m_y = y; } template<typename T, typename V> T myTemplate<T,V>::plus() { return (T)(this->m_x + this->m_y); } #endif
运行结果:
24