我如何在C中模仿Java / C ++的面向类方法?

时间:2013-10-06 08:25:02

标签: c pointers

这就是我想要做的事情:

1)我想要一个实例化数据结构的函数。

void instantiateCDB(void);

2)我还想要一个更新实例化的数据结构的函数,并返回一个指向数据结构的const指针(使其成为只读)

我知道这可以用C ++ / Java完成。但是它也可以在C中完成吗?

我想写的程序流程是:

main(){
   instantiateCDB();    // Allocates a CDB 
   const struct canDataBlock * cdb = getUpdateSystem();
}

// But the best function definitions that I can come up with is this.

struct canDataBlock * instantiateCDB() {
     static struct canDataBlock cdb = {0};
     return &cdb;
}

const struct canDataBlock * getUpdateSystem() {

     struct canDataBlock * cdb = instantiateCDB();
     return &cdb;
 }

问题是:如果将instantiateCDB函数中的写/读访问权限声明为无效,如何访问数据结构?如果我要返回已分配的数据结构,则用户可以更改canDataBlock,从而失去其完整性。我想要发生的只是getUpdateSystem()可以更改instantiateCDB()函数实例化的数据结构的值。我该如何解决这个问题? C中是否有另一种我不知道的技术。如果有,请教我。 :)

2 个答案:

答案 0 :(得分:2)

有一种名为opaque data pointer的模式,它可能对您有所帮助。请参阅http://en.wikipedia.org/wiki/Opaque_data_type

答案 1 :(得分:2)

C中的OO可以部分模拟(单词“模拟”而不是“实现”是故意选择的),例如继承可以通过嵌套基础结构作为“派生”结构的第一个成员来模拟,在这种情况下它是可以将派生的指针结构“upcast”为“base”结构,就像在C中一样,可以保证指向struct的指针可用于访问指向第一个成员的指针。 根据上下文,您可以使用opaque数据类型来隐藏实现细节。要模拟私有和公共数据,您可以提供完整的结构声明,包括所有成员,但仍然将某些成员隐藏为不透明或无效指针。

struct myclass_privdata;
struct myclass { int data; /* public member */ 
struct myclass_privdata* data_priv; /* private simulation*/ }

您还可以使用函数指针模拟成员函数,但仍需要显式传递对象引用(并初始化它)。

struct S;
void do(struct S* this_p) { }
struct S { void (*do_smth)(struct s* this_p); } s;
s->do_smth = do;
s->do_smth(s);

也许你可以在glib library object model中找到灵感。关于这个话题甚至还有book

但是,对于这个主题,最好的建议是保持语言风格,而不是试图做不应该使用的语言(例如,在C中实现oop通常会导致样板代码增加低功能值 - 它使代码看起来像是用OOP编写的,而事实上并非如此,并且使代码看起来对于那些以“原生”风格编程的人来说很难看。

解决你的问题。

1)函数返回数据实例通常实现为返回malloced()指针

的函数
#include <stdlib.h>
struct S {int i; };
struct S* S_alloc(void) { return malloc(sizeof(S)); }

返回指向静态数据的指针的代码几乎肯定是一个麻烦,因为所有引用都将引用同一个对象。并通过void instantiateCDB判断(void);声明我怀疑它确实是你想要做的。

2)我怀疑你真的“想要一个更新实例化的数据结构的函数并返回一个指向数据结构的const指针(使其成为只读)” - 因为调用者仍然会有一个非const刚刚传递给这种函数的指针。