C++拾趣——使用多态减少泛型带来的代码膨胀

栏目: C++ · 发布时间: 6年前

内容简介:泛型编程是C++语言中一种非常重要的技术,它可以让我们大大减少相似代码编写量。有时候,我和同事提及该技术时,称它是“一种让编译器帮我们写代码的技术”。C++是一门静态语言,它最终的编译成果是可以直接运行于冯诺依曼体系的计算机上,而不像其他动态语言,需要运行于虚拟机等容器中。由于对运行效率得追求,C++也是一门类型精确的语言,即object是什么类型,在编译时往往就要确定好,这种方式可以称为数据的静态绑定。上例中,我们只写了一个call_function模板函数,但是最终编译器会将其翻译成为两个独立的函数,

泛型编程是C++语言中一种非常重要的技术,它可以让我们大大减少相似代码编写量。有时候,我和同事提及该技术时,称它是“一种让编译器帮我们写代码的技术”。

C++是一门静态语言,它最终的编译成果是可以直接运行于冯诺依曼体系的计算机上,而不像其他动态语言,需要运行于虚拟机等容器中。由于对运行效率得追求,C++也是一门类型精确的语言,即object是什么类型,在编译时往往就要确定好,这种方式可以称为数据的静态绑定。

template<class T>
void call_function(T& f) {
	f();
};

class PrintA {
public:
	virtual void operator ()() {
		std::cout << "Print A" << std::endl;
	}
};

class PrintB : public PrintA {
public:
	virtual void operator ()() {
		std::cout << "Print B" << std::endl;
	}
};

int main() {
	PrintA a;
	PrintB b;
	call_function(a);
	call_function(b);
	return 0;
}

上例中,我们只写了一个call_function模板函数,但是最终编译器会将其翻译成为两个独立的函数,分别是call_function<PrintA>()和call_function<PrintB>()。这也是之前所述“一种让编译器帮我们写代码的技术”的表现。

我们逆向上述代码来验证下

C++拾趣——使用多态减少泛型带来的代码膨胀

上图我们看到call_function<PrintA>()和call_function<PrintB>()方法的地址是不同的。这就意味着,这两个方法拥有各自的代码逻辑。再上升一个层次去看,使用call_function的模板方法的类有多少种,就会产生多少个相应的特化方法。于是我们的确只写了一个模板方法,但是编译器最终帮我们生成了多个,于是便发生了“代码膨胀”。

编译器将类型特化,即精确指定了类型,这就使得C++程序在运行时直接跳转到相应函数地址就行,而不需要做类型判别后去路由。这也是C++高效的一个重要原因。

除了静态绑定,C++还有半动态绑定。这也是C++实现多态的技术基础。我们可以使用该技术,部分的解决泛型技术带来的“代码膨胀”的问题。

以上例为例,我们只要增加如下方法就行

void call(PrintA& f) {
	f();
}

然后调用call(a)和call(b)

C++拾趣——使用多态减少泛型带来的代码膨胀

可以看到,两次调用的call方法指向了同一个地址。于是不管call方法操作的类型有多少个,它都没有导致代码的膨胀。

需要指出的是,泛型和多态在上例中,体现了“空间”和“时间”的选择问题。当我们在做优化代码时,往往最终会走到“时间换空间”或者“空间换时间”的选择中。

上例泛型技术,生成了多份函数。在调用时,方法对应的函数地址是确定的,于是这是种调用是高效的。这是“空间换时间”的案例。

上例多态技术,只生成了一份代码。在调用时,call方法需要找到object的虚表,然后计算出虚函数的地址,最后才能调用相应的虚函数。这个过程没有直接call一个地址快。这是“时间换空间”的案例。

目前CPU的发展已经进入瓶颈,磁盘的空间却越来越便宜。很多人可能觉得“空间换时间”是个更好的选择,其实不可以一概而论。因为如果程序的最终编译产物小,其在CPU指令缓存中发生了cache miss也可能变小,最终效率可能还是可观的。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

用户力:需求驱动的产品、运营和商业模式

用户力:需求驱动的产品、运营和商业模式

郝志中 / 机械工业出版社 / 2015-11-1 / 59.00

《用户力:需求驱动的产品、运营和商业模式》从用户需求角度深刻阐释了互联网产品设计、网络运营、商业模式构建的本质与方法论! 本书以“用户需求”为主线,先用逆向思维进行倒推,从本质的角度分析了用户的需求是如何驱动企业的产品设计、网络运营和商业模式构建的,将这三个重要部分进行了系统性和结构化的串联,然后用顺向思维进行铺陈,从实践和方法论的角度总结了企业究竟应该如围绕用户的真实需求来进行产品设计、网......一起来看看 《用户力:需求驱动的产品、运营和商业模式》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器