首先我要说的是,我在C和C ++方面都有相当多的经验。但是,我正在用C开始一个新项目,我一直在使用面向对象的语言很长时间(C#和C ++),我无法想出一种以过程语言封装功能的有效方法。我的第一个想法是简单地依靠我的OO知识并将其结构化为:
struct Foo
{
int x;
char *y;
};
struct Foo *new_Foo()
{
return (struct Foo *)malloc(sizeof(struct Foo));
}
void Foo_member_function(struct Foo *foo, int z)
{
foo->x = z;
}
但这似乎很乏味,与C的精神相反。更不用说它是一个穷人的OO。
这个程序最终会变得相当大,所以从一个好的设计组织开始是至关重要的。我想,随着C语言的多年发展,某些设计模式已经发展到如何最好地构建代码以实现可维护性。与函数式编程非常相似,我希望过程式编程具有干净且可读性的范例。
相关文章和书籍的指示也是可以接受的。
答案 0 :(得分:16)
这是一种非常正常和明智的做法。但是尽量不要在头文件中公开struct layout,这样你就可以更灵活地实现它并更好地管理你的依赖项。
有关详细信息,请参阅Opaque pointer。
答案 1 :(得分:12)
你所建议的是我在做这样事情的那些日子里总是写C程序的方式。我不认为这是“穷人的OO”,我认为这是合理的程序编程实践。
我会观察一些关于你的C代码的事情:
答案 2 :(得分:3)
嗯...我们以前只使用命名约定...... Ergo:str *用什么常见的数据结构做什么?所以也许只需要使用C#语法和s /./_/ g?
......并且没有继承......
但是看看光明的一面......你可以使用指向指针指向函数的指针返回指针指向指针int!哦,快乐!
我最好的建议是学习Java的经验教训(并通过推理C#)并构建你的库以避免副作用...更多typdefs ==少头疼......如果你的工作如何遵循这位圣人建议请告诉我; - )
干杯。基思。
答案 3 :(得分:3)
这是编写C程序的一种非常合理的方法。还有另一个大型应用程序,它的功能几乎相同 - 称为Linux内核。在那里使用了一些近乎OO的特征:
答案 4 :(得分:1)
C是一种低级语言,在这方面,根据代码函数和模块组织数据结构非常有用。
我建议您在任何想要创建数据对象的地方使用typedef和枚举。使用宏或静态函数根据需要初始化,分配和“销毁”。
答案 5 :(得分:1)
我同意上述建议。你正在以最好的方式做到这一点..如果你想用C编程。
当然,您可以编写一个预处理器来为您自动生成这些声明和事物..也许使用“类”声明...将您想要成为函数的函数放在类中...等等。
但我们在这里得到的是一个简单的C ++到C编译器。为什么不用C ++编程,使用真正的C ++编译器,使用干净的接口,只需将C ++代码与C代码链接起来?你需要在C和C ++中编码的原因是什么?或者如果需要,从编译器生成C代码并将输出C代码与您需要的任何其他代码一起编译。
答案 6 :(得分:0)
我已经在一个项目上工作了一段时间,库需要在C中,但我希望有一些形式的OO功能。我正在做一些与此类似的事情。更多细节。
struct klass {
char * value;
void (*set_value) (struct klass *, const char *);
void (*destroy) (struct klass *);
};
static void
klass_method_set_value (struct klass * k, const char * value) {
if (k->value == NULL) {
}
}
static void
klass_object_desetroy (struct klass * k) {
free (k);
k = NULL;
}
static void
klass_method_destroy (struct klass * k) {
klass_object_destroy (k);
}
static struct klass *
klass_object_init (void) {
struct klass * obj = (struct klass *) malloc (sizeof (struct klass*) );
/* members */
obj->value = NULL;
/* methods */
obj->set_value = klass_method_set_value;
obj->destroy = klass_method_destroy;
return obj;
}
struct klass *
klass_new (void) {
return klass_object_init ();
}
如果出现问题,请原谅我;写得快一点。