4

this通过显式传递指针,可以在 C 中模拟成员函数。可以通过在每个对象中显式存储指向函数指针全局数组的指针来模拟虚函数。美好的。

现在我的问题是,人们真的会这样做吗?我想知道是否值得教授这种技术,因为我不想教 C 新生在现实世界中几乎从未使用过的东西。

(我需要为已经熟悉 OOP 的人填写为期两周的 C 入门课程的最后一天。)

是否有任何相关项目、库或框架以所描述的方式在 C 中模拟 OO?

4

5 回答 5

8

我在 C 方面有大约 20 年的经验。它是我学习的第一个编译语言,我从不需要继续前进,所以它一直是 C,而且只有 C。我经常在工作和家里编写代码。我已经发布了一个无锁数据结构库。我认为我是一个称职的 C 程序员。

关于您的问题,OO 包含许多概念。例如,一个是实例化,例如具有 new() 和 delete() 以及给定实体(堆栈、列表等)的实例的库。C 支持这一点,当然,它是一种非常实用且有用的方法。我已经使用这种方法大约十五年了。

许多年前,我开始尝试另一个在 C++ 中得到很好支持的 OO 概念,即继承。我想要一个包含其他实体的实体。然后问题是暴露所包含实体的 API。你可以做到,但事实是,C 语言并没有自然地表达这样的概念和方法。这不是我现在使用的东西。

我的建议是;刀就是刀,叉就是叉。您可以将其中一个用作另一个,但效果不佳。C 自然不支持某些(重要的)OO 概念,例如继承。不要试图让 C 做这些事情。如果您想这样做,请使用 C++。

于 2012-08-12T12:17:48.413 回答
3

是的,他们有。

是否有任何相关项目、库或框架以所描述的方式在 C 中模拟 OO?

我不会因为没有一流的语言支持而称其为“模拟”。请参阅GObject

于 2012-08-12T11:41:13.823 回答
2

许多项目在 C 代码库中使用面向对象的范例。由于各种原因,他们不直接使用 CPP。对于系统级或性能密集型项目,其他语言不适合。所以这是cpp和c之间的战斗。

为什么人们在 C 中模拟 OO 而不是完整的 CPP 是激烈争论的话题。Linus torvalds 曾经说过一句名言,CPP 编译器是不值得信赖的。他对 CPP 生成的代码缺乏信心。

Linux 内核是在 C 中实现 OO 设计模式的一个很好的例子。您可以在这个 lwn.net 文章系列中了解 Linux 内核是如何做到的:

第1部分

第2部分

互联网上有一个广泛的免费文档,其中涵盖了用 C 语言实现的全方位 OO 设计模式。

ooc.pdf

您可以在同一条路上找到许多其他项目。

例子:

pjsip

苏菲亚

于 2012-08-12T12:05:21.070 回答
1

它可能不会在实践中使用,但是学习成员函数和以对象为第一个参数的函数之间的等价概念是非常有价值的。将这个概念放在他们的脑海中将帮助他们解决他们在未来遇到的许多问题。

日复一日,我看到人们在 Stack Overflow 上询问为什么指向将成员函数传递给需要函数指针的东西不起作用的问题,以及类似的事情。他们认为成员函数只是作为对象一部分的一些神奇函数,使整个情况过于复杂。如果他们已经意识到成员函数等同于将对象作为第一个参数的函数,那么他们遇到的问题(即调用方法他们将不知何故需要成员函数指针和对象),如以及可能的解决方案(以某种方式单独传递对象,或进行某种捕获对象的闭包)变得显而易见。显然,太多人只是假装 OO 是“神奇的”而不理解这一点。

在函数式编程中,我们经常教人们如何纯粹根据函数操作来编写数据结构和局部变量以及所有这些东西。并不是说这是实用的——它可能效率低下——但这让他们对函数的力量印象深刻。它可以帮助他们以不同的方式理解事物。如果他们编写编译器或其他东西,也许在路上,这些等价物会派上用场。

计算机科学就是关于等价和约简,以及如何从另一个问题考虑一个问题。我们将 SAT-3 简化为子集和,不是因为这实际上是我们实际解决 SAT-3 问题的方式,而是因为这告诉我们子集和是 NP 完全的。

每隔一段时间,我就会遇到一段由其他人编写的代码,其中非实例方法将指向结构的指针作为参数,我看到一个模式和一个灯泡在我的脑海中熄灭,我说,啊哈,这可以重新分解为实例方法,因为我知道这种等价性。所以你看,知道这些等价性也有助于我们编写更好、更简单的代码。

于 2012-08-12T21:51:03.103 回答
0

查看 TI 的“DSP 算法标准”/xDAIS 框架。

有一个通用的 C API,每个符合 DSP 算法的实现都实现了(抱歉重言式)。对所有这些“艺术”的需求源于 DSP 世界中常见的几个问题:

  • 相对较小的 RAM
  • 多个数据通道(通常并行/并发)
  • 复杂的算法使用模式
  • 别的我忘记了

该标准和框架旨在使 DSP 工程师更容易使用 3rd 方 DSP 算法。

有一个接口可以配置算法实例并查询其内存需求(基于配置),并且有实际管理内存的支持函数。

一些内存区域,暂存器,可以临时分配并在算法实例处于活动状态时分配给它,而在它处于非活动状态时将其从算法实例中取出并提供给另一个实例,有效共享。

还有将实例内存缓冲区移动到碎片整理内存的功能(和 API)。

还有更多,但我需要重新阅读文档以回忆细节。

例如,参见IALG_*()ALG_*()接口方法。

此外,还有一些工具可以验证通用 API 的实现。第三方可以请求 TI 对其进行官方验证。

一些相关链接:spru352g.pdfspru360e.pdf

于 2012-08-12T14:06:13.730 回答