为什么旧代码的目标文件可以使用使用通用编程范例的新代码,即使模板是静态绑定的?

Why and how can an object file of old code use new code that uses the generic programming paradigm even though templates are static binding?

这是一个与我之前问过的完全不同的问题,这就是我发布此问题的原因。

我想将我的主题定义为一个主观问题,它激发了解释 "why" 和 "how" 的答案。根据 Help Center 规则,这是允许的。

为了使我的问题更具建设性,我为您提供了更好地解释我的主题的资源。

来自C++ SuperFAQ下的问题

"Can you give me a simple reason why virtual functions (dynamic binding, dynamic polymorphism) and templates (static polymorphism) make a big difference?"

作者说,“......一个程序员可能会写一些代码,由他们的曾曾曾祖父编写的框架调用。没有必要改变曾曾祖父的代码。其实对于虚函数的动态绑定,如果你只剩下目标文件,甚至高曾祖父写的源代码丢失了25年前,它甚至不需要recompiled.Even ,那个古老的目标文件将调用新的扩展名而不会出现任何问题。"

他接着说,"That is extensibility, and that is OO and generic programming for powerful reusable abstraction."

此外,我最近阅读了一篇由 C++ 的创建者 Bjarne Stroustrup 撰写的论文,名为“Why C++ is not just an Object-Oriented Programming Language”。在他的论文中,他将一种语言或技术定义为面向对象的,当且仅当它直接支持:

  1. Abstraction – providing some form of classes and objects.

  2. Inheritance – providing the ability to build new abstractions out of existing ones.

  3. Run-time polymorphism – providing some form of run-time binding.

他还简要提到了泛型编程。

6.7 Generic Programming - A major theme in the C ++ community over the last few years has been the development of techniques exploiting the template mechanism.

通过阅读这两个资源,我可以理解旧代码如何能够通过面向对象的范例使用新代码。但是,我不明白旧代码如何通过泛型编程(在本例中为模板)使用新代码,因为泛型编程使用静态绑定。从我之前的相关问题 Ben Voigt 评论说,

""old"模板代码要与"new"模板代码合并,需要将两者一起编译。"

C++ SuperFAQ 似乎暗示(对于 OO 和泛型编程)旧代码不必重新编译新代码以便使用新代码,并且您应该只需要旧代码中的目标文件。从而保持代码的可重用性。

有人可以回答 "why" 和 "how" 即使模板是静态绑定,旧代码的目标文件也可以使用使用通用编程范例的新代码吗?

编辑

我想更详细地解释下面的答案,因为这将帮助我了解更多,也可能帮助其他人理解。由于泛型编程使用静态绑定,旧代码和新代码的源代码都必须重新编译"together"才能使代码重用生效。这意味着,如果您只有旧代码的目标文件,您将无法使用新代码,因为这需要 dynamic/late 绑定,绑定时间为 运行。

简短的回答是不能。我猜这就是您链接的答案的第一句话的意思:

They can improve reuse by letting old code call new code provided at run time (virtual functions) or compile time (templates).

[已强调]

要使现有代码使用模板,您必须重新编译。这意味着您必须从(某种形式的)源代码开始,而不是目标文件(至少不是大多数人认为的普通目标文件)。

我声称旧代码不仅要重新编译才能使用新代码,而且还必须更改才能使用新代码,即。 A *a = new A => A *a = new B,即使A包含了用virtual关键字声明的成员函数,而B已经覆盖了它