如何在c中实现一个类

时间:2012-10-23 13:51:04

标签: c++ c

  

可能重复:
  How do you implement a class in C?

在我的测试中,我被告知我需要找到一种在C

中实现以下类的方法
class A
{
    private:
      int a,b;
    public:
      void func1();
      int c,d;
    protected:
      int e,f;
      void fun();
};

C编译器是否也支持访问说明符private,public和protected inside结构?

8 个答案:

答案 0 :(得分: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等。编译器不会阻止你写入它们,但你显然是这样做的您自己承担风险,并且明确表示您不应该访问这些成员(直接复制或类似的除外)。

答案 1 :(得分:2)

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

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

myclass.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
}

的main.c

#include "myclass.h"

myclass* mc = myclass_construct();
...

答案 2 :(得分: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 */ }

答案 3 :(得分: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”标头中,以模拟受保护的访问。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

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

A.H

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

A.C

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

main.c中:

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

答案 6 :(得分: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 */
}

答案 7 :(得分:0)

C中没有类,但是通过使用struct和functions,你可以在没有继承和多态的情况下完成基本过程。