質問

C ++言語が提供します virtual 関数。純粋なC言語の実装の制約の中で、同様の効果をどのように達成できますか?

役に立ちましたか?

解決

盗まれた ここ.

C ++クラスから

class A {
protected:
    int a;
public:
    A() {a = 10;}
    virtual void update() {a++;}
    int access() {update(); return a;}
};

Cコードフラグメントを導出できます。の3つのC ++メンバー関数 class A Out-Ofl-Line(Standalone)コードを使用して書き換えられ、アドレスによってコレクションされ、名前付きの構造体に収集 A_functable. 。のデータメンバー A そして、関数テーブルと組み合わせて名前のc構造体に A.

struct A;

typedef struct {
    void (*A)(struct A*);
    void (*update)(struct A*);
    int (*access)(struct A*);
} A_functable;

typedef struct A{
    int a;
    A_functable *vmt;
} A;

void A_A(A *this);
void A_update(A* this);
int A_access(A* this);

A_functable A_vmt = {A_A, A_update, A_access};

void A_A(A *this) {this->vmt = &A_vmt; this->a = 10;}
void A_update(A* this) {this->a++;}
int A_access(A* this) {this->vmt->update(this); return this->a;}

/*
class B: public A {
public:
    void update() {a--;}
};
*/

struct B;

typedef struct {
    void (*B)(struct B*);
    void (*update)(struct B*);
    int (*access)(struct A*);
} B_functable;

typedef struct B {
    A inherited;
} B;

void B_B(B *this);
void B_update(B* this);

B_functable B_vmt = {B_B, B_update, A_access};

void B_B(B *this) {A_A(this); this->inherited.vmt = &B_vmt; }
void B_update(B* this) {this->inherited.a--;}
int B_access(B* this) {this->inherited.vmt->update(this); return this->inherited.a;}

int main() {
    A x;
    B y;
    A_A(&x);
    B_B(&y);
    printf("%d\n", x.vmt->access(&x));
    printf("%d\n", y.inherited.vmt->access(&y));
}

必要以上に精巧ですが、ポイントを獲得します。

他のヒント

@GCC ....仮想関数はオブジェクトのベースクラスで宣言され、その後「オーバーライデン」またはサブクラスで実装されます。つまり、車両のベースクラスがあり、2つのサブクラス、オートバイと自動車を作成するとします。基本クラスは、addtires()の仮想関数を宣言し、サブクラスはこの関数を実装し、各サブクラスはそれを異なる方法で実装します。ただし、車には4つのホイールがあり、オートバイには2があります。ただし、CまたはC ++の構文はできません。お役に立てれば

仮想関数は、C ++のオブジェクト方向の機能です。それらは、現在持ち込んでいるタイプではなく、特定のオブジェクトインスタンスに依存する方法を指します。

言い換えれば、オブジェクトをバーとしてインスタンス化する場合、それをfooにキャストする場合、仮想メソッドはまだインスタンス化されていたもの(バーで定義されている)であり、他の方法はfooのものです。

仮想関数は通常、vtablesによって実装されます(それはあなたがより多くの研究を行うためです;))。

貧しい人間のオブジェクトとして構造体を使用し、その中に関数ポインターを保存することにより、Cの同様のことをシミュレートできます。

(より正確には、非仮想的な機能により、どのメソッドをどのように分類するかを曖昧にしますが、実際にはC ++は現在のタイプを使用していると思います。)

ここ 仮想関数の説明です。

Cには継承の概念がないため、プレーンCに仮想関数を実装する方法はありません。

アップデート:以下のコメントで説明したように、構造と関数ポインターを使用して、ストレートCの仮想関数に似たことを行うことができます。ただし、「真の」仮想関数を備えたC ++のような言語に慣れている場合、おそらくC近似がはるかにエレガントではなく、使用が難しいことがわかります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top