滴水恩情 发表于 2022-6-20 08:32:06

聊聊 C# 和 C++ 中的 泛型模板 底层玩法

最近在看 C++ 的方法和类模板,我就在想 C# 中也是有这个概念的,不过叫法不一样,人家叫模板,我们叫泛型,哈哈,有点意思,这一篇我们来聊聊它们底层是怎么玩的?
一:C++ 中的模板玩法

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

玩之前先看看格式: templaterettype funcname (parameter list) { }。
说实话,我感觉 C++ 这一点就做的非常好,人家在开头就特别强调了,这是一个 template,大家不要搞错了,按照这个格式,我们来一个简单的 Sum 操作,参考代码如下:
#include <iostream>

//求和函数
template <typename T> T getsum(Tt1, Tt2) {
        return t1 + t2;
}

int main() {

        int sum1 = getsum<int>(10, 10);

        long sum2 = getsum<long>(20, 20);

        printf("output: int:sum=%d, long: sum=%ld", sum1, sum2);
}https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e6d7f55c0a874a36b074d17dbad18d75~tplv-k3u1fbpfcp-zoom-1.image
接下来我就很好奇,这种玩法和 普通方法 调用有什么不同,要想找到答案,可以用 IDA 去看它的静态汇编代码。
https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7982884cc8fc443fa8c642114f0d0395~tplv-k3u1fbpfcp-zoom-1.image
从静态反汇编代码看,当前生成了两个函数符号分别为: j_??$getsum@H@@YAHHH@Z 和 j_??$getsum@J@@YAJJJ@Z,现在我们就搞清楚了,原来一旦给 模板 指定了具体类型,它就生成了一个新的函数符号。
乍一看这句话好像没什么问题,但如果你心比较细的话,会发现一个问题,如果我调用两次 getsum 方法,那会生成两个具体函数吗? 为了寻找答案,我们修改下代码:
int main() {

        int sum1 = getsum<int>(10, 10);

        int sum2 = getsum<int>(15, 15);
}然后再用 IDA 查看一下。
https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4bf20d4abf0c43699a3b26fa8a1a51d7~tplv-k3u1fbpfcp-zoom-1.image
哈哈,可以发现这时候并没有生成一个新的函数符号,其实往细处说:j_??$getsum@H@@YAHHH@Z是函数签名组合出来的名字,因为它们签名一致,所以在编译阶段必然就一个了。
2. 类模板的玩法

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

还是那句话,开头一个 template 暴击,告诉你这是一个模板
来源:https://www.cnblogs.com/huangxincheng/archive/2022/06/17/16384668.html
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 聊聊 C# 和 C++ 中的 泛型模板 底层玩法