Как можно реализовать виртуальные функции C ++ в C [дублировать

StackOverflow https://stackoverflow.com/questions/3113583

  •  29-09-2019
  •  | 
  •  

Вопрос

Язык C ++ обеспечивает virtual функции. В пределах ограничений реализации языка чистого C, как можно достичь аналогичного эффекта?

Это было полезно?

Решение

Похищена от здесь.

Из класса C ++

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

Фрагмент кода C может быть получен. Три функции члена C ++ class A переписаны с использованием кода вне линии (автономного) и собираются адресом в структуру, названную 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 .... Виртуальная функция объявляется в базовом классе объекта, а затем «переопределяется» или реализована в подклассных классах. т.е., скажем, у вас есть класс базы автомобилей, и вы создаете два подкласса: мотоцикл и автомобиль. Базовый класс будет объявлять виртуальную функцию addTires (), а затем классы SUB будут реализовать эту функцию, и каждый суб -класс будет реализовать ее по -разному. Автомобиль имеет 4 колеса, где у мотоцикла есть 2. Я не могу дать вам синтаксис для C или C ++. Надеюсь это поможет

Виртуальные функции являются функцией объектной ориентации C ++. Они ссылаются на методы, которые зависят от конкретного экземпляра объекта, а не на том, какой тип вы в настоящее время несете их.

Другими словами: если вы создаете экземпляр объекта в виде стержня, то поднимайте его в Foo, виртуальные методы все равно будут теми, кто был в экземпляре (определяется в баре), в то время как другие методы будут из Foo.

Виртуальные функции обычно реализуются с помощью VTables (это для вас, чтобы провести больше исследований;)).

Вы можете смоделировать подобные вещи в C, используя структуры в качестве объектов бедного человека и сохранения указателей функций в них.

(Более правильно, не виртуальные функции делают их неоднозначными, из какого класса следует извлечь метод, но на практике я считаю, что C ++ использует текущий тип.)

Здесь это описание того, что такое виртуальные функции.

Невозможно реализовать виртуальные функции в простом C, потому что C не имеет понятия наследования.

Обновлять:Как обсуждается в комментариях ниже, можно сделать что -то похожее на виртуальные функции в прямых C, используя структуры и указатели функций. Однако, если вы привыкли к такому языку, как C ++, который имеет «истинные» виртуальные функции, вы, вероятно, найдете приближение C гораздо менее элегантным и труднее использовать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top