读《模板的声明和实现为何要放在头文件中?》有感
来源:互联网 发布:完美主义 知乎 编辑:程序博客网 时间:2024/05/22 12:56
先看一个普通类的生成顺序:
//test.h
#ifndef _TEST_ #define _TEST_#include <iostream>#include <string>class Test {public:Test(int m);~Test();void sum(int n);private:int m;};#endif
//test.cpp
#include "test.h"Test::Test(int m){this->m = m;}Test::~Test(){}void Test::sum(int n){std::cout<<m+n<<std::endl;}//main.cpp
#include "test.h"int main(){ Test t(5);t.sum(3);system("pause");return 0;}编译器首先编译main.cpp生成main.obj,执行到Test t(5)是,到test.h中查找整个类的定义,由于test.h中全是声明,所以main.obj只能处于监听(我暂且这样思考)。编译test.cpp生成test.obj,通知main.obj的监听,定义已经编译完了,存在定义。main.obj得到定义,连接obj,生成exe。
来看看模板:
//test.h
#ifndef _TEST_ #define _TEST_#include <iostream>#include <string>template<typename T>class Test {public:Test(T m);~Test();void sum(T n);private:T m;};#endif
//test.cpp
#include "test.h"template<typename T>Test<T>::Test(T m){this->m = m;}template<typename T>Test<T>::~Test(){}template<typename T>void Test<T>::sum(T n){std::cout<<m+n<<std::endl;}
//main.cpp
#include "test.h"
#include "test.h"int main(){ Test<int> t(5);t.sum(3);system("pause");return 0;}编译出错!因为main.obj在test.h没有找到定义之后发起一个监听(我的理解),编译器就去编译test.cpp了。由于在test.cpp中没有模板具现化的代码(没有与Test<int>匹配的定义),也就没有能响应main.obj监听的通知,main.obj就不能实例化Test<int> t(5)这个对象,因为找不到定义。
如果:
#include "test.cpp"int main(){ Test<int> t(5);t.sum(3);system("pause");return 0;}直接包含test.cpp的话,main.obj就先到test.cpp中查找,这不是一个监听的过程,是一个主动的查找过程,直接匹配带入一下,找到合适定义,就能生成对象了,程序也就能成功执行了。这样有一个缺点,在main.cpp中包含了test.cpp和test.h,内容过大,想想看都不舒服。
为了让main.obj能直接找到Test<int>的定义,那就把Test<T>的声明和定义都放在同一个文件中把。这样比直接包含cpp美观点。
个人思维,可能不严谨。
原文地址:模板的声明和实现为何要放在头文件中?
- 读《模板的声明和实现为何要放在头文件中?》有感
- 转贴:模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板函数的声明和定义为何不能分开放在两个文件中?
- C++中模板的声明和实现应该放在同一个文件中
- 从汇编角度看为什么模板函数声明和定义要放在头文件上
- 模板类成员函数的定义和声明为什么要放在一个文件中
- 模板类成员函数的定义和声明为什么要放在一个文件中
- 模板类成员函数的定义和声明为什么要放在一个文件中
- C++ 模板类的实现为何放在.h中
- eclipse 不自动编译java文件的问题
- TNSAnalysis
- NDK 之大门开启
- Extjs 文本框 TextField 添加点击(onclick)事件方法
- VS.NET环境下实现日志系统的几种方式
- 读《模板的声明和实现为何要放在头文件中?》有感
- c# 字符、汉字等转换
- 《C语言深度剖析》学习笔记1
- ServiceManager & SystemService
- 批处理从FTP下载 最新文件
- struts2中拦截器的使用(一)
- loadrunner 常见 error
- 82天
- IOS开发问题解决之限制UITextField输入特定位数小数时,Done按钮失效