栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

模板 template<typename T> 和 template<class T>区别

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

模板 template<typename T> 和 template<class T>区别

最近在看 C++ 的方法和类模板,我就在想 C# 中也是有这个概念的,叫泛型.

一、类模板 template 和 template区别


C++ 标准:
template 用于基础数据类型, T可以是int char 等
template  用于复制数据类型,T :string ,类等


实际情况:
二者都可以用于各种数据类型。
Bjarne.Stroustrup说:
The 'typename' keyword can also be used as an alternative to 'class' in template declarations. For example:
template void f (T );
Being an indifferent typist and always short of screen space, I prefer the shorter:
template void f (T );

特例:
当T是一个类,而这个类又有子类(假设名为 innerClass) 时,应该用 template:
typename T::innerClass   myInnerObject;
这里的 typename 告诉编译器,T::innerClass 是一个类,程序要声明一个 T::innerClass 类的对象,而不是声明 T 的静态成员,而 typename 如果换成 class 则语法错误。
模板是实现代码重用机制的一种工具,实质就是实现类型参数化,即把类型定义为参数。C++提供两种模板:函数模板,类模板。
函数模板
 

#include "stdafx.h"
#include 
using namespace std;

template  // 或者 template
T my_max(T a, T b)
{
    return a>b ? a : b;
}

int main()
{
    int nresult = my_max(10, 25);
    char nresult2 = my_max('a', 'b');
    cout << "nresult=" << nresult << "nnresult2=" << nresult2 << endl;

    return 0;
}

类模板

#include "stdafx.h"
#include 
using namespace std;

template  // 或者 template
class CMax
{
public:
    CMax(T a, T b)
    {
        m_a = a;
        m_b = b;
    }

    T GetMax()
    {
        return m_a > m_b ? m_a : m_b;
    }
private:
    T m_a;
    T m_b;
};


int main()
{
    CMax myMax(10,25);
    int nresult = myMax.GetMax();

    CMax myMax2('a', 'b');
    char nresult2 = myMax2.GetMax();

    cout << "nresult=" << nresult << "nnresult2=" << nresult2 << endl;

    return 0;
}

二、C++ 中的模板具体玩法


毕竟 C++ 是兼容 C 语言,而 C 是过程式的玩法,所以 C++ 就出现了两种模板类型,分别为:​​函数模板​​​ 和 ​​类模板​​,下面简单分析一下。
1. 函数模板的玩法
玩之前先看看格式: ​​template rettype funcname (parameter list) { }​​。
说实话,我感觉 C++ 这一点就做的非常好,人家在开头就特别强调了,这是一个 ​​template​​​,大家不要搞错了,按照这个格式,我们来一个简单的 ​​Sum​​ 操作,参考代码如下:

#include 

//求和函数
template  T getsum(T  t1, T  t2) 
{
  return t1 + t2;
}

int main() 
{
  int sum1 = getsum(10, 10);
  long sum2 = getsum(20, 20);
  printf("output: int:sum=%d, long: sum=%ld", sum1, sum2);
}

我就很好奇,这种玩法和 ​​普通方法​​​ 调用有什么不同,要想找到答案,可以用 ​​IDA​​ 去看它的静态汇编代码。


从静态反汇编代码看,当前生成了两个函数符号分别为: ​​j_??$getsum@H@@YAHHH@Z​​​ 和 ​​j_??$getsum@J@@YAJJJ@Z​​​,现在我们就搞清楚了,原来一旦给 ​​模板​​ 指定了具体类型,它就生成了一个新的函数符号。
乍一看这句话好像没什么问题,但如果你心比较细的话,会发现一个问题,如果我调用两次 ​​getsum​​ 方法,那会生成两个具体函数吗? 为了寻找答案,我们修改下代码:

 

int main() 
{
  int sum1 = getsum(10, 10);
  int sum2 = getsum(15, 15);
}

然后再用 IDA 查看一下。

 

哈哈,可以发现这时候并没有生成一个新的​​函数符号​​​,其实往细处说:​​j_??$getsum@H@@YAHHH@Z​​​ 是​​函数签名​​组合出来的名字,因为它们签名一致,所以在编译阶段必然就一个了。

2. 类模板的玩法
首先看下类模板的格式:​​template class className { };​​还是那句话,开头一个 ​​template​​ 暴击,告诉你这是一个模板 , 接下来上一段代码:

#include 
template  class Calculator
{
public:
  T getsum(T a1, T b1) 
  {
    return a1 + b1;
  }
};

int main() 
{

  Calculator cal1;
  int sum1 = cal1.getsum(10, 10);

  Calculator cal2;
  int sum2 = cal2.getsum(15, 15);

  printf("output: sum1=%d, sum2=%ld", sum1,sum2);
}

接下来直接看 IDA 生成的汇编代码。

 

从上面的方法签名组织上看,有点意思,​​类名+方法名​​ 柔和到一个函数符号上去了,可以看到符号不一样,说明也是根据模板实例化出的两个方法。
 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1018469.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号