0

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

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

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

C 编译器是否还支持访问说明符 private、public 和 protected 内部结构?

4

8 回答 8

8

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

也没有private

struct A
{
   int a, b;
   int c, d;
   int e, f;
};

void func1( struct A* );

void fun( struct A* );

但一切都是公开的。

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

protected没有真正的意义,因为没有继承。您可以通过将您的细节或其功能暴露给某些内部模块来实现“友谊”,但友谊与受保护的不同,后者在 C 中根本不存在。

在您的课程中,您已经公开了两个成员,但是如果我们“隐藏”结构 A,我们会隐藏所有内容,因此请提供 getter 和 setter。

或者,我们可以“隐藏”结构的一部分,例如: struct A1;

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

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

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

于 2012-10-23T13:51:53.007 回答
4

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

我的班级.h

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);

我的班级.c

#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
}

主程序

#include "myclass.h"

myclass* mc = myclass_construct();
...
于 2012-10-23T14:17:32.290 回答
1

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);}

struct Foo的bar成员只能被 foo.c 中的函数访问。缺点是您不能在堆栈上创建 Foo 。同样,您可以将定义放入单独的“foo_private.h”标头中以模拟受保护的访问。

于 2012-10-23T14:05:45.327 回答
1

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 */ }
于 2012-10-23T13:55:31.010 回答
0

即使没有语言支持,也有众所周知的方法可以在 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 */
}
于 2012-10-23T14:24:20.557 回答
0

类是 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);
}
于 2012-10-23T14:02:19.980 回答
0

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

于 2012-10-23T14:27:52.187 回答
0

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

于 2012-10-23T13:54:35.080 回答