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

しかし、すべてが公開されています。

物事をよりカプセル化するために、構造体 A の実際の実装の詳細を非表示にし、パブリック メソッドを使用した前方宣言のみを表示します。

protected継承がないため、意味がありません。詳細またはその機能を特定の内部モジュールに公開することで、一種の「友情」を実装できますが、友情は保護されたものと同じではなく、C 内には存在できません。

あなたのクラスでは、2 つのメンバーを公開しましたが、構造体 A を「非表示」にするとすべてが非表示になるため、代わりにゲッターとセッターを提供します。

別の方法として、次のように構造体の一部を「隠す」こともできます。

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

ただし、プライベート部分の割り当てを開始する必要があるため、「面倒」になります(Cにはスマートポインターやデストラクタがないため、メモリ管理にはもっと注意する必要があります).

多くの C API がこれに使用するのは、「プライベート」変数を「予約済み」と呼ぶ命名規則です。多くの場合、reserved1、reserved2 などです。コンパイラはそれらへの書き込みを停止しませんが、明らかに自己責任で行います。であり、これらのメンバーにアクセスしてはならないという意図は明らかです (直接コピーなどを除く)。

于 2012-10-23T13:51:53.007 に答える
4

これは、C でプライベート カプセル化を行う方法です。この概念は、不透明型、またはより正式には不完全型として知られています。

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();
...
于 2012-10-23T14:17:32.290 に答える
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 に答える
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 に答える
0

C言語にはクラスはありませんが、構造体と関数を使えば継承やポリモーフィズムなしで基本的な処理を行うことができます。

于 2012-10-23T14:27:52.187 に答える
0

言語サポートがなくても、C でこれらのほとんどを実現するよく知られた方法があります。手動でできないことの 1 つは、非公開と保護を区別することです。

/* 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++ クラスをシミュレートできます...

于 2012-10-23T13:54:35.080 に答える
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; }  

main.c:

#include "A.h"
int main () {
  struct A* a = A_new();
  A_func1(a);
}
于 2012-10-23T14:02:19.980 に答える