一个、“经典模式”失败

我们学过C++的人都知道。在C++中组织代码的经典模型是:将函数或类的声明和定义部分分开在不同的文件之中   ,

即一般将声明放在一个.h的头文件里而定义在放在一个.cpp文件之中,当然这的确是写代码的一种非常优良的风格。但问题

是假设将这样的“经典模型”应用到模版上时就会发生连接上错误。

比如:

文件“A.h”

#include"iostream"
using namespace std;
#pragma once
template<typename T>
class A
{
private:
T t;
public:
A(T d)
{t = d;}
~A(void){}
void fun();
};

文件“A.cpp”

#include "A.h"
#include"iostream"
using namespace std;
template<typename T>
void A<T>::fun()
{
cout<<t<<"这个是A类"<<endl;
}

主文件main.cpp:

#include<iostream>
#include"A.h"
using namespace std; int main()
{
A<int> a(1);
a.fun();
}

将上面的程序编译连接执行,会发现编译通过,但连接会报错。

上述这样的“经典模型”不再适用与C++模版的主要原因是:模版类或模版函数与一般的C++类或函数不同。对于模版

类或模版函数仅仅有在遇到不同类型的应用时才会实例化出详细不同的函数或类,所以上面的程序连接错误的主要原因是

:模版类A未被实例化,编译器会分别的去编译那三个文件。由于A的定义和A的调用分别处在不同的.cpp文件里,所以当

A.cpp被编译时因未见到详细类型调用所以没实例化。而main.cpp在编译时编译器仅仅从A.h看到了A类的声明,所以编译

器会如果程序在别的地方提供了A的详细定义。所以也没有实例化A。

以至于在连接过程中发现A<int>没有被实例化的定

义而终于报错。

二、“包括模型”的出现

“包括模型”攻克了上述问题,即将模版类的定义和声明都写在同一个.h文件就可以。

这样仅仅要主文件包括了这个.h头文件

则在主文件编译时就会从该.h文件里找到模版类或函数的定义从而产生实例化。

比如:文件“A.h”

#include"iostream"
using namespace std;
#pragma once
template<typename T>
class A
{
private:
T t;
public:
A(T d)
{t = d;}
~A(void){}
void fun()
{
cout<<t<<"这个是A类"<<endl;
}
};

主文件“main.cpp”

#include<iostream>
#include"A.h"
using namespace std; int main()
{
A<int> a(1);
a.fun();
}

能够执行通过。

三、显示实例化

显示实例化的出现主要是为了模版代码的组织形式的更加灵活性,同一时候也是对于“包括模型”的某些缺点的弥补,

在“包括模型”中有一个非常大的不足就是:将全部的代码都写入一个.h头文件里这会明显的添加头文件的开销,且同一时候

对于应用该模版的每个.cpp文件来说都要把此.h文件包括进去,显然这样做会更进一步的使整个程序的开销变的非常

大,所以解决问题的一个办法就是“显示实例化”。

在最上面的那个样例中连接报错的原因是A<int>未被实例化,找不到详细的定义。所以假设我们还是想沿用经得

起历史考验的“经典模型”时。就须要自己去显示实例化。

“显示实例化”的详细形式非常easy:仅仅要在模版定义的.cpp文件里加上一句有显示实例化指示符template引导的须要

实例化实体的声明就可以。

比如:对于最上面的样例:再要在A.cpp中在上以下的声明就可以:

template A<int>;

比如完整样例改动后例如以下:

文件“A.h”

#include"iostream"
using namespace std;
#pragma once
template<typename T>
class A
{
private:
T t;
public:
A(T d)
{t = d;}
~A(void){}
void fun();
};

文件“A.cpp”

#include "A.h"
#include"iostream"
using namespace std;
template A<int>;//显示实例化
template<typename T>
void A<T>::fun()
{
cout<<t<<"这个是A类"<<endl;
}

主文件“mian.cpp”

#include<iostream>
#include"A.h"
using namespace std; int main()
{
A<int> a(1);
a.fun();
}

执行通过!

四、“包括模型”与“显示实例化”的结合

事实上“显示实例化”也有其自己的弊端。那就是对于模版类或模版函数的某一个详细类型的显示实例化必须唯一。不能反复

实例化,这也就是说在程序中你必须自己去跟踪模版的每个实例化,否则就会出错。

这种问题在达到一定规模的大程序中

是相当困难的。所以将“包括模型”与“显示实例化”结合就是取各自之长。能够依据详细问题的要求而任意选择不同的模型。

详细的做法是:任然将模版的定义和声明都分开写在两个不同的文件。但这两个文件都必须是.h的头文件。且定义文件要

用#include包括声明文件。

所以当自己希望使用“包括模型”时,仅仅须要把定义文件.h包括在应用.cpp文件就可以。而当自己须要使用

”显示实例化“时,仅仅须要将声明.h文件包括在应用文件之中,而且同一时候在模版定义.h文件间的需要显示详细的示例可以是实例。

版权声明:本文博客原创文章。博客,未经同意,不得转载。

C++基于该模型模板包括节目外实例的更多相关文章

  1. JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化

    前言:之前发表过一篇  JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果分享(你值得拥有) ,收到很多园友的反馈,当然也包括很多诟病,因为上篇只是将功能实现了,很多细节都没有处理 ...

  2. 微软BI 之SSAS 系列 - 基于雪花模型的维度设计

    基于雪花模型的维度以下面的 Product 产品与产品子类别,产品类别为例. DimProduct 表和 DimProductSubcategory 表有外键关系,而 DimProductSubcat ...

  3. AIOps探索:基于VAE模型的周期性KPI异常检测方法——VAE异常检测

    AIOps探索:基于VAE模型的周期性KPI异常检测方法 from:jinjinlin.com   作者:林锦进 前言 在智能运维领域中,由于缺少异常样本,有监督方法的使用场景受限.因此,如何利用无监 ...

  4. Halcon编程-基于形状特征的模板匹配

    halcon软件最高效的一个方面在于模板匹配,号称可以快速进行柔性模板匹配,能够非常方便的用于缺陷检测.目标定位.下面以一个简单的例子说明基于形状特征的模板匹配.      为了在右图中,定位图中的三 ...

  5. 中国快递包裹总量的预测-基于SARIMA模型

    code{white-space: pre;} pre:not([class]) { background-color: white; }if (window.hljs && docu ...

  6. 基于RBAC模型的通用企业权限管理系统

    1. 为什么我们需要基于RBAC模型的通用企业权限管理系统 管理信息系统是一个复杂的人机交互系统,其中每个具体环节都可能受到安全威胁.构建强健的权限管理系统,保证管理信息系统的安全性是十分重要的.权限 ...

  7. UML和模式应用4:初始阶段(4)--需求制品之用例模型模板示例

    1. 前言 UP开发包括四个阶段:初始阶段.细化阶段.构建阶段.移交阶段: UP每个阶段包括 业务建模.需求.设计等科目: 其中需求科目对应的需求制品包括:设想.业务规则.用例模型.补充性规格说明.词 ...

  8. ASP.NET MVC —— Model之一模型模板

    http://www.cnblogs.com/lzhp/archive/2013/03/25/2981650.html Mvc model系列文章主要分为三部分:Model Templates,Mod ...

  9. 基于EPOLL模型的局域网聊天室和Echo服务器

    一.EPOLL的优点 在Linux中,select/poll/epoll是I/O多路复用的三种方式,epoll是Linux系统上独有的高效率I/O多路复用方式,区别于select/poll.先说sel ...

随机推荐

  1. Android数据库高手秘籍(一)——SQLite命令

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/38461239 要想熟练地操作不论什么一个数据库.最最主要的要求就是要懂SQL语言, ...

  2. A Game of Thrones(10) - Jon

    Jon climbed the steps slowly, trying not to think that this might be the last time ever. Ghost padde ...

  3. Spring3.0官网文档学习笔记(七)--3.4.2

    3.4.2 依赖与配置的细节     3.4.2.1  Straight values (primitives, Strings, and so on)     JavaBeans PropertyE ...

  4. 获取Google音乐的具体信息(方便对Google音乐批量下载)

    Google音乐都是正版音乐, 不像百度所有都是盗链, 并且死链也多. 但有一个麻烦就是要下载Google音乐的时候得一个一个的点击下载链接, 进入下载页面再点"下载", 才干下载 ...

  5. Python数据结构-序表

    序表解包: list=['aa','bb','cc'] [a1,a2,a3]=list

  6. Eclipse上运行Python,使用PyDev

    转自:http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-pydev/index.html 级别: 初级 郑 伟芳 (zhengwf@c ...

  7. [置顶] JQuery实战总结三 标签页效果图实现

    在浏览网站时我们会看到当我们鼠标移到多个选项卡上时,不同的选项卡会出现自己对应的界面的要求,在同一个界面上表达了尽量多的信息.大大额提高了空间的利用率.界面的切换效果也是不错的哦,这次自己可以实现啦. ...

  8. Max Sum (hdu 1003 简单DP水过)

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  9. u-boot 的bootcmd 和bootargs详解,烧写分析

    下面链接这篇文章也非常重要,介绍DM3X的一系列烧写步骤和设置方法 http://www.61ic.com/Article/DaVinci/TMS320DM3x/201204/41827.html U ...

  10. Android---53---多线程下载

    采用HttpURLConnection HttpURLConnection从继承URLConnection,它也可以被用来发送到指定的网站GET求 POST求. 办法: int getResponse ...