Polymorphism (in C) [duplicate]

岁酱吖の 提交于 2019-12-17 15:32:14

问题


Possible Duplicate:
How can I simulate OO-style polymorphism in C?

I'm trying to better understand the idea of polymorphism with examples from languages I know; is there polymorphism in C?


回答1:


This is Nekuromento's second example, factored in the way I consider idiomatic for object-oriented C:

animal.h

#ifndef ANIMAL_H_
#define ANIMAL_H_

struct animal
{
    // make vtable_ a pointer so they can be shared between instances
    // use _ to mark private members
    const struct animal_vtable_ *vtable_;
    const char *name;
};

struct animal_vtable_
{
    const char *(*sound)(void);
};

// wrapper function
static inline const char *animal_sound(struct animal *animal)
{
    return animal->vtable_->sound();
}

// make the vtables arrays so they can be used as pointers
extern const struct animal_vtable_ CAT[], DOG[];

#endif

cat.c

#include "animal.h"

static const char *sound(void)
{
    return "meow!";
}

const struct animal_vtable_ CAT[] = { { sound } };

dog.c

#include "animal.h"

static const char *sound(void)
{
    return "arf!";
}

const struct animal_vtable_ DOG[] = { { sound } };

main.c

#include "animal.h"
#include <stdio.h>

int main(void)
{
    struct animal kitty = { CAT, "Kitty" };
    struct animal lassie = { DOG, "Lassie" };

    printf("%s says %s\n", kitty.name, animal_sound(&kitty));
    printf("%s says %s\n", lassie.name, animal_sound(&lassie));

    return 0;
}

This is an example of runtime polymorphism as that's when method resolution happens.

C1x added generic selections, which make compile-time polymorphism via macros possible. The following example is taken from the C1x April draft, section 6.5.1.1 §5:

#define cbrt(X) _Generic((X), \
    long double: cbrtl, \
    default: cbrt, \
    float: cbrtf \
)(X)

Type-generic macros for math functions were already available in C99 via the header tgmath.h, but there was no way for users to define their own macros without using compiler extensions.




回答2:


Almost all implementations of runtime polymorphism in C will use function pointers, so this is the basic building block.

Here is a simple example when procedure runtime behavior changes depending on it's argument.

#include <stdio.h>

int tripple(int a) {
    return 3 * a;
}

int square(int a) {
    return a * a;
}

void transform(int array[], size_t len, int (*fun)(int)) {
    size_t i = 0;
    for(; i < len; ++i)
        array[i] = fun(array[i]);
}

int main() {
    int array[3] = {1, 2, 3};
    transform(array, 3, &tripple);
    transform(array, 3, &square);

    size_t i = 0;
    for (; i < 3; ++i)
        printf("%d ", array[i]);

    return 0;
}

Using function pointers you can create virtual tables and use it to create "objects" that will be treated uniformly, but behave differently at runtime.

#include <stdio.h>

struct animal_vtable {
    const char* (*sound)();
};

struct animal {
    struct animal_vtable methods;
    const char* name;
};

const char* cat_sound() {
    return "meow!";
}

const char* dog_sound() {
    return "bark!";
}

void describe(struct animal *a) {
    printf("%s makes \"%s\" sound.\n", a->name, a->methods.sound());
}

struct animal cat = {{&cat_sound}, "cat"};
struct animal dog = {{&dog_sound}, "dog"};

int main() {
    describe(&cat);
    describe(&dog);

    return 0;
}



回答3:


There's no intrinsic support for polymorphism in C, but there are design patterns, using function pointers, base 'class' (structure) casts, etc., that can provide a logical equivalent of dynamic dispatch. The GTK library is good example.




回答4:


I guess, you already checked Wikipedia article on polymorphism.

In computer science, polymorphism is a programming language feature that allows values of different data types to be handled using a uniform interface.

According to that definition, no, C doesn't natively support polymorphism. For instance, there is no general function for acquiring absolute value of a number (abs and fabs are for integers and doubles respectively).

If you're also familiar with C++, take a look at OOP inheritance and templates - those are mechanisms for polymorphism there.



来源:https://stackoverflow.com/questions/8194250/polymorphism-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!