一个、“经典模式”失败

我们学过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. B. 沙漠之旅(分组背包)

    B. 沙漠之旅 Time Limit: 1000ms Case Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: % ...

  2. ssh, maven and eclipse 那些破事

    Unix根据该理念keep it simple, keep it stupid.可在j2ee有keep it complex, keep it smart. 所以,我彻底晕菜. 最后能活着把sprin ...

  3. Enum实现单例模式

    package com.wjy.effective; public enum Singleton { INSTANCE; private int numa; private int numb; pub ...

  4. hdu2159(二维完全背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2159 题意:打怪,还有最后一级,忍耐度有限m,问在杀怪数量上限为s的情况下能否获取n经验而通关,且忍耐 ...

  5. MyEclipse 2013 新功能介绍

    http://pan.baidu.com/share/link?shareid=3310814720&uk=4012618212 下载地址 HTML5 Mobile Projects MyEc ...

  6. H3C TE BGP拓扑排错报告

                                                                                       BGP排错报告 故障一:PPP链路 ...

  7. 浅谈JAVA ThreadPoolExecutor(转)

    这篇文章分为两部分,前面是ThreadPoolExecutor的一些基本知识,后一部分则是Mina中一个特殊的ThreadPoolExecutor代码解析.算是我的Java学习笔记吧. 基础 在我看来 ...

  8. 创建和关联内容数据库到指定Web应用程序和站点集

    创建和关联内容数据库到指定Web应用程序和站点集         一个Web应用程序不限于使用单个内容数据库.SharePoint同意你关联多个内容数据库到Web应用程序.原因之中的一个是基于内容数据 ...

  9. 2014ACM/ICPC亚洲区域赛牡丹江站现场赛-K ( ZOJ 3829 ) Known Notation

    Known Notation Time Limit: 2 Seconds      Memory Limit: 65536 KB Do you know reverse Polish notation ...

  10. cocos2dx 3.1从零学习(六)——CocosStudio(VS2013project导入及环境设置)

    导入libCocosStudio.libExtensions.libGUI 新建的project例如以下图: 加入现有项目 右键解决方式.例如以下操作: watermark/2/text/aHR0cD ...