ToB企服应用市场:ToB评测及商务社交产业平台

标题: 聊聊 C# 和 C++ 中的 泛型模板 底层玩法 [打印本页]

作者: 滴水恩情    时间: 2022-6-20 08:32
标题: 聊聊 C# 和 C++ 中的 泛型模板 底层玩法
最近在看 C++ 的方法和类模板,我就在想 C# 中也是有这个概念的,不过叫法不一样,人家叫模板,我们叫泛型,哈哈,有点意思,这一篇我们来聊聊它们底层是怎么玩的?
一:C++ 中的模板玩法

毕竟 C++ 是兼容 C 语言,而 C 是过程式的玩法,所以 C++ 就出现了两种模板类型,分别为:函数模板 和 类模板,下面简单分析一下。
1. 函数模板的玩法

玩之前先看看格式: template  rettype funcname (parameter list) { }。
说实话,我感觉 C++ 这一点就做的非常好,人家在开头就特别强调了,这是一个 template,大家不要搞错了,按照这个格式,我们来一个简单的 Sum 操作,参考代码如下:
  1. #include <iostream>
  2. //求和函数
  3. template <typename T> T getsum(T  t1, T  t2) {
  4.         return t1 + t2;
  5. }
  6. int main() {
  7.         int sum1 = getsum<int>(10, 10);
  8.         long sum2 = getsum<long>(20, 20);
  9.         printf("output: int:sum=%d, long: sum=%ld", sum1, sum2);
  10. }
复制代码

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

从静态反汇编代码看,当前生成了两个函数符号分别为: j_??$getsum@H@@YAHHH@Z 和 j_??$getsum@J@@YAJJJ@Z,现在我们就搞清楚了,原来一旦给 模板 指定了具体类型,它就生成了一个新的函数符号。
乍一看这句话好像没什么问题,但如果你心比较细的话,会发现一个问题,如果我调用两次 getsum 方法,那会生成两个具体函数吗? 为了寻找答案,我们修改下代码:
  1. int main() {
  2.         int sum1 = getsum<int>(10, 10);
  3.         int sum2 = getsum<int>(15, 15);
  4. }
复制代码
然后再用 IDA 查看一下。

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

首先看下类模板的格式:template   class className { };

还是那句话,开头一个 template 暴击,告诉你这是一个模板
来源:https://www.cnblogs.com/huangxincheng/archive/2022/06/17/16384668.html
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4