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

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

18
задан nicael 21 May 2014 в 18:49
поделиться

4 ответа

Украдено из здесь .

Из класса C ++

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

можно получить фрагмент кода C. Три функции-члены C ++ класса 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));
}

Более сложный, чем необходимо, но он передает суть.

29
ответ дан 30 November 2019 в 08:10
поделиться

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

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

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

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

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

0
ответ дан 30 November 2019 в 08:10
поделиться

Здесь - описание виртуальных функций.

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

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

-1
ответ дан 30 November 2019 в 08:10
поделиться

@GCC....Виртуальная функция объявляется в базовом классе объекта и затем "переопределяется" или реализуется в подклассах. Т.е., скажем, у вас есть базовый класс Vehicle и вы создаете два подкласса, Motorcycle и Automobile. Базовый класс объявляет виртуальную функцию AddTires() Затем подклассы реализуют эту функцию, причем каждый подкласс реализует ее по-своему. Автомобиль имеет 4 колеса, а мотоцикл - 2. Я не могу дать вам синтаксис для C или C++, однако. Надеюсь, это поможет

1
ответ дан 30 November 2019 в 08:10
поделиться