如何在 C 中实现类

how to implement a class in c

本文关键字:实现      更新时间:2023-10-16

可能的重复:
如何在C中实现一个类?

在我的测试中,我被告知我需要找到一种方法来在 C 中实现以下类

class A
{
private:
int a,b;
public:
void func1();
int c,d;
protected:
int e,f;
void fun();
};

此外,C 编译器是否支持访问说明符私有、公共和受保护的内部结构?

C 中没有类,只有结构。C++有课程。

也没有private

struct A
{
int a, b;
int c, d;
int e, f;
};
void func1( struct A* );
void fun( struct A* );

但一切都是公开的。

为了使事情更加封装,您将隐藏结构 A 的实际实现细节,并仅显示带有公共方法的前向声明。

protected没有真正的意义,因为没有继承。您可以通过将您的详细信息或其功能公开给某些内部模块来实现"友谊",但友谊与受保护不同,这根本不存在于 C 中。

在你的类中,你已经公开了两个成员,但是如果我们"隐藏"结构A,我们就会隐藏所有内容,所以提供getter和setter。

或者,我们可以"隐藏"结构的一部分,如下所示: 结构 A1;

struct A
{
struct A1 * privatePart;
int b, c;  // public part     
};

尽管它变得"混乱",因为您必须开始分配私有部分(请记住,在 C 中没有智能指针或析构函数,因此您必须更加小心内存管理)。

许多 C API 为此使用的是一种命名约定,它们将"私有"变量称为"保留",通常是保留 1、保留 2 等。编译器不会阻止您写入它们,但您显然需要自担风险,并且意图很明显,您不应该访问这些成员(直接复制或类似成员除外)。

这就是你在 C 中进行私有封装的方式。这个概念被称为不透明类型,或者更正式地说,不完整类型。

我的班级

typedef struct myclass myclass;

myclass* myclass_construct (void);
void     myclass_set_x (myclass* this, int x);
int      myclass_get_x (const myclass* this);
void     myclass_destruct (myclass* this);

我的班级

#include "myclass.h"
struct myclass
{
int x; // this is a private variable
};

myclass* myclass_construct (void)
{
myclass* instance = malloc (sizeof(myclass));
if(instance == NULL) { /* error handling */ }
instance->x = 0;
return instance; 
}
void myclass_set_x (myclass* this, int x)
{
this->x = x;
}
int myclass_get_x (const myclass* this)
{
return this->x;
}
void myclass_destruct (myclass* this)
{
free(this);
}
static myclass_private_member (something_t s)
{
// pure private function, do something internal here
}

主.c

#include "myclass.h"
myclass* mc = myclass_construct();
...

C 语言中没有访问控制,否则,您可以通过自由函数近似C++类成员函数的某些功能:

struct A { int a, b, c, d, e, f; };
void A_func1(struct A * th) { /* use "th->a" etc. */ }
void A_fun(struct A * th) { /* ditto */ }

用法:

struct A a;
A_func1(&a);
A_fun(&a);

正如@CashCow所说,通过正确构建翻译单元,您可以获得相当数量的实现和接口分离。例如:

mylib.h:(运送这个)

struct A;
void A_func1(struct A *);

mylib_secret_impl.c:(只发送二进制文件!

#include "mylib.h"
struct A { int a, b, c, d, e, f; };
void A_fun(struct A * th) { /* ... */ }
void A_func1(struct A * th) { /* use A_fun(th) and members of *th */ }

C 不支持访问说明符,但是您可以使用仅在实现文件中定义的匿名结构来模拟它们的某些功能。

// foo.h
typedef struct Foo Foo;
Foo * FooAlloc(int bar);
void  FooFree(Foo *);
// foo.c
struct Foo {
int bar;
};
Foo * FooAlloc(int bar){
Foo * f = malloc(sizeof(*f));
f->bar = bar;
return f;
}
void FooFree(Foo * f){free(f);}

结构体 Foo 的bar成员只能由 foo.c 中的函数访问。缺点是您无法在堆栈上创建Foo。同样,您可以将定义放入单独的"foo_private.h"标头中以模拟受保护的访问。

在结构中,您可以在函数上编写指针来模拟C++类...

类是一个C++概念,而不是C概念。但是,您可以通过使用指针和 PIMPL 在 C 语言中实现一些 OO 设计功能。

以下是我在 C 中实现类的方法:

struct privateA;
struct A {
struct A_private* private;
int c,d;
};
extern void A_func1(struct A*);
extern struct A* A_new();

交流电

struct A_private {
int a,b;
int e,f;
};
static struct A_private* A_private_new() {
struct A_private_new* this = malloc(sizeof(struct A_private);
this->a = 0;
this->b = 0;
this->e = 0;
this->f = 0;
}
struct A* A_new() {
struct A* this = malloc(sizeof (struct A));
this->private = A_private_new();
this->c = 0;
this->d = 0;
}
void A_func1(struct A* this) { this->c = 12; }
static void A_fun(struct A* this) { this->d = 7; }  

主.c:

#include "A.h"
int main () {
struct A* a = A_new();
A_func1(a);
}

有一些众所周知的方法可以在 C 语言中实现大部分目标,即使没有语言支持也是如此。您无法手动执行的一件事是区分私有和受保护。

/* Foo.h */
struct Foo {
int c, d;
};
struct Foo* newFoo(); /* you can't create these on the stack */
void Foo_func1(struct Foo*);

诀窍只是隐藏呼叫者不应访问的内容。与使用完全不透明类型不同,我们可以选择直接公开公共成员,而无需函数调用。

/* Foo.c */
struct Foo_private {
struct Foo pub;
int a, b;
int e, f; /* note I'm not distinguishing private */
};
struct Foo* newFoo()
{
struct Foo_private *f = malloc(sizeof(*f))
/* initialize */
return &f->pub;
}
struct Foo_private* cast(Foo *f)
{
/* can do cunning things with offsets for inheritance,
but this is the easy case */
return (Foo_private *)f;
}
void Foo_func1(Foo *f)
{
struct Foo_private *fp = cast(f);
/* access private members here */
}

C 中没有类,但通过使用结构和函数,您可以在没有继承和多态性的情况下执行基本过程。