1

In order to follow a prepared design document I want to create virtual function in C. Is there any best practice to do that? As @imreal suggested we can use function pointers to convert C structures works similar to C++ classes but how can we make sure that virtual base class functions are overrides derived class functions.

In my case I need this feature to follow the documentation but I think it can be also useful when we are converting a C++ code to C. This is required when combining a C++ code with a C code.

M.Khd
  • 85
  • 1
  • 10
  • And what would be a purpose of a virtual function in C? – Eugene Sh. May 25 '17 at 16:27
  • You could revise the design document. – Nick is tired May 25 '17 at 16:29
  • 3
    Create a struct with function pointers, write a functions to act as constructors to assign different functions to those pointers. Every function takes a self/this pointer to be able to access the data members. – imreal May 25 '17 at 16:29
  • You mean a virtual method? C doesn't have methods; it doesn't even have classes! – ikegami May 25 '17 at 16:36
  • Use an [object system](https://github.com/CObjectSystem/COS) (it's like answering "use C++" but different!). This question has no meaning without an object system - any way you find to give it meaning just means you defined your own object system instead of using an existing library or language's one. – Alex Celeste May 25 '17 at 16:52
  • UseCplusPlus(); override; (this question is too abstract for C). – ThingyWotsit May 25 '17 at 16:55
  • @Leushenko thanks for introducing object system – M.Khd May 25 '17 at 17:32

4 Answers4

4

The language does not offer it as a feature but you can achieve the same functionality.

Create a struct with function pointers:

typedef struct Base Base_t;
struct Base {
    void (*f1)(Base_t* self);
    void (*f2)(Base_t* self);

    int dat1;
    int dat2;
};

Write a functions to act as constructors to assign different functions to those pointers.

Base constructor1()
{
    Base l = {func1, func2, 0, 0};
    return l;
}

Base constructor2()
{
    Base l = {func3, func4, 6, 13};
    return l;
}

Call the methods:

Base a = constructor1();
a.f1(&a);

Every function takes a self/this pointer to be able to access the data members.

Live example:

http://ideone.com/LPSd65

imreal
  • 10,178
  • 2
  • 32
  • 48
  • 2
    It would be beneficial for readability to use better names... – Attie May 25 '17 at 16:37
  • At this point, why are you using C instead of C++? – Donnie May 25 '17 at 16:41
  • 1
    @Donnie There can be lots of reasons to force/prefer `C` over `C++` and simulating OOP on `C` is the topic of numerous articles, but I'm just answering the OP's question. – imreal May 25 '17 at 16:42
  • How can I overload base class functions in this way? – M.Khd May 25 '17 at 16:44
  • @M.Khd Create different functions constructors create an object with other functions. – imreal May 25 '17 at 16:45
  • 2
    @imreal - I know. We've all done it too, but it's worth asking the question so that people think about why they're choosing what they're choosing. I was perhaps a bit to flippant in the way I phrased it. – Donnie May 25 '17 at 16:49
2

No you can't. 'virtual' is not part of the C vocabulary, neither is 'access level'

Henri
  • 91
  • 1
  • 5
  • C++ is created by C so there should always be a way to implement C++ features in C. – M.Khd May 25 '17 at 16:45
  • 1
    @M.Khd, That makes no sense unless you are suggesting making changes to the C compiler. – ikegami May 25 '17 at 17:05
  • @ikegami we can add function pointers to structures to create structures that are similar to classes. So it should also be possible to modify them in a way to create virtual functions too. – M.Khd May 25 '17 at 17:22
  • 1
    @M.Khd, Never said otherwise. Of course you can write a C (or Perl or VB) program that has the same *effect* as a C++ program, and of course you can *approximate* some C++ features in those languages. But you can't actually give C those features just because C is written in C++. – ikegami May 25 '17 at 17:27
  • @Henri it depends on if you want to print a, so called, "kerstboom" ;) – Jan Eerland May 27 '17 at 19:10
1

In C there is no such concept as a 'virtual' function.

Instead I would advise that you look at my answer.

Fundamentally:

  • Define a struct
  • Provide a suite of functions to act upon that struct
  • If a particular usage requires different functionality, then call a different function
Ðаn
  • 10,934
  • 11
  • 59
  • 95
Attie
  • 6,690
  • 2
  • 24
  • 34
0

There is no builtin language support, but you can get the same general functionality of using a default implementation if a special one is missing. Something like this maybe:

#include <stdio.h>

struct animal {
    const char *name;
    void (*move)(struct animal *);
};

void fly(struct animal *a)
{
    printf("soaring %s\n", a->name);
}

void walk(struct animal *a)
{
    printf("walk %s, walk\n", a->name);
}

void animal_move(struct animal *a)
{
    void (*move)(struct animal *) = a->move ? : walk;
    move(a);
}

int main(void)
{
    struct animal elephant = { .name = "elephant" };
    struct animal bird = { .name = "bird", .move = fly };

    animal_move(&elephant);
    animal_move(&bird);
    return 0;
}
Ðаn
  • 10,934
  • 11
  • 59
  • 95
wkz
  • 2,203
  • 1
  • 15
  • 21