C是面向对象的程序员

时间:2009-09-20 20:01:21

标签: c oop

学过Java和C ++后,我学会了OO方式。我想开始一个相当雄心勃勃的项目,但我想用C语言做。我知道如何将问题分解为类以及如何将它们转换为类层次结构。我知道如何将功能抽象为抽象类和接口。我甚至有点精通以有效的方式使用多态。

问题在于,当我遇到问题时,我只知道如何做到这一点是以面向对象的方式。我变得过于依赖面向对象的设计理念和方法。

我想学习如何以严格的程序方式思考。如何在缺少类,接口,多态,函数重载,构造函数等的世界中做事。

如何仅使用非面向对象的struct表示复杂概念?你如何避免缺乏函数重载?以程序方式思考的一些提示和技巧是什么?

8 个答案:

答案 0 :(得分:4)

程序方法一方面是数据结构,另一方面是算法。然后,您将获取数据结构并将其传递给算法。如果没有封装,那么执行此操作需要更高的纪律,如果您提高抽象级别以使其更容易正确执行,那么您在C中执行了相当大的OO部分。

答案 1 :(得分:1)

我认为你有一个好的计划。在C语言中完全以OO的方式做事,虽然很有可能,但是你很快就会放弃它。 (不要与语言作斗争。)

如果你想要一个关于将OO方式映射到C方式的哲学陈述,部分原因是将对象创建推向一个层次。模块仍然可以将其对象实现为黑盒子,并且您仍然可以使用合理的编程风格,但实际上隐藏对象实际上太痛苦了,因此调用者分配它并将其传递下来,而不是模块分配它并将其恢复原状。你通常会在getter和setter上游戏,或者将它们实现为宏。

还要考虑到你提到的所有这些抽象都是普通structs之上的相对较薄的层,所以你并不是真的离你想做的事情很远。它的包装不是很好。

答案 2 :(得分:1)

C工具包由函数,函数指针和宏组成。函数指针可用于模拟多态性。

答案 3 :(得分:1)

你正在采取反向旅行的老C程序员为学习OO。

即使在c ++之前,在C语言中使用了标准的OO技术。

它们包括使用指向srtuct的指针定义结构(通常称为...) 然后在结构中定义指针函数,并在运行时初始化那些指向相关函数的指针。 所有这些函数作为第一个参数被收到结构指针。

答案 4 :(得分:1)

不要以完整的OOP方式思考C语言。如果必须使用C,则应学习程序编程。这样做不会比学习如何实现C中的所有OOP功能花费更多的时间。此外,基本封装可能很好,但是当你模仿它们时,许多其他OOP功能会带来性能上的开销(而不是在设计语言时)支持OOP)。如果严格遵循C ++设计方法将每个小东西表示为对象,那么开销可能会很大。编程语言在设计中具有特定目的。当你打破边界时,你总是需要支付一些费用。

答案 5 :(得分:0)

在C中执行多态行为的标准方法是使用函数指针。您会发现许多C API(例如标准qsort(3)bsearch(3))将函数指针作为参数;一些非标准的,例如qsort_r采用函数指针和上下文指针(在这种情况下为thunk)除了被传递回回调之外没有任何其他目的功能。在处理函数对象(例如仿函数)时,上下文指针的功能与面向对象语言中的this指针完全相同。

另见:

答案 6 :(得分:0)

不要认为你必须搁置你对面向对象工作的了解 - 你可以"program into the language"

在主要面向对象工作经验之后,我不得不在C工作。 C允许某些级别的对象概念通过。在工作中,我必须在C中实现一个红黑树,用于sweep-line algorithm以查找一组段中的交叉点。由于算法使用了不同的比较函数,我最终使用函数指针来实现与Scheme中的lambda或C#中的委托相同的效果。它运行良好,并且允许平衡树可重复使用。

平衡树的另一个特性是使用void指针来存储任意数据。同样,C中的void和函数指针很痛苦(如果你不知道它们的来龙去脉),但它们可以用来近似创建一个通用的数据结构。

最后一点说明:使用正确的工具完成工作。如果您想简单地使用C来掌握程序技术,那么选择一个非常适合程序方法的问题。我在这个问题上没有选择(用C语言写的遗留应用程序,人们要求世界并拒绝进入21世纪),所以我必须要有创造力。如果您想编写命令行数据包检查程序,C非常适合机器的低/中抽象。

答案 7 :(得分:0)

尽量不要在C语言中使用OOP。但是,如果需要,请使用结构。对于功能, 为参数取一个结构,就像这样:

typedef struct{
    int age;
    char* name;
    char* dialog;
} Human;
void make_dialog(Human human){
    char* dialog="Hi";
    human.dialog=dialog;
}

的工作原理完全类似于python的self或类似的东西,并且可以访问属于该类的其他函数:

void get_dialog(Human human){
    make_dialog(human);
    printf(human.dialog);
}