f



C version of C++'s virtual functions

How can C be used to created a "Vtable" like C++'s virtual functions? I bet
this involves struct.

Lost

        Bill





-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----
0
some81 (23)
8/6/2003 4:17:43 AM
comp.lang.c 30656 articles. 5 followers. spinoza1111 (3246) is leader. Post Follow

3 Replies
503 Views

Similar Articles

[PageSpeed] 24

In 'comp.lang.c', "Bill Cunningham" <some@some.net> wrote:

> How can C be used to created a "Vtable" like C++'s virtual functions? I bet
> this involves struct.

You have to fiddle with pointers to functions.

-- 
-ed- emdelYOURBRA@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
0
emdelYOURBRA (457)
8/6/2003 4:58:06 AM
"Bill Cunningham" <some@some.net> wrote in message
> How can C be used to created a "Vtable" like C++'s virtual functions? > I
bet
> this involves struct.

typedef struct
{
  void (*pt)(void *ptr, double t, double *x, double *y);
  double (*len)(void *ptr);
  void *ptr;
}LINEINTERFACE;

This is an interface for a 2D line. There are two functions, one to get the
x, y position for a point t (0-1) along the length, the other to get the
length of the line.

Now lets define two lines

typedef struct
{
  double x1;
  double y1;
  double x2;
  double y2;
} STRAIGHT;

typedef struct
{
  double x[4];
  double y[4];
} BEZIER;

Now you can write functions

void getpoint(void *straight, double t, double *x, double *y)
{
  STRAIGHT *line = straight;
  *x = line->x1 + t * (line->x2 - line->x1);
  *y = line->y1 + t * (line->y2 - line->y1);
}

And so on.

You the set up your LINEINTERFACES with these function pointers, plus a
pointer to the line data (either a bezier or a striaght line).

Now we have a client function

void movespaceship(LINEINTERFACE *path)
{
  double len;
  double t;
  double x;
  double y;

  len = path->len(path->ptr);

  for(t=0;t<=1;t += 1/len)
  {
     path->pt(path->ptr, t, &x, &y);

     displayshipat(x,y);
     dorestofprogram();
  }
}

Note that we can now add any type of line to this function, as long as we
can calculate a length and a point t. The ship could go in a spiral, or a
zigzag, or anything else.


0
Malcolm
8/6/2003 6:12:59 PM
"Bill Cunningham" <some@some.net> wrote in message
> Great. Does the STRAIGHT *line=straight;
> Make straight the client through the line pointer to the interface
> straight?
> That's what it looks like to me. Kind of like the new in C++. That's
> what it is doing here right?
>
In C++ every member function takes a this pointer as its first parameter
(hidden).
When you use virtual functions, a hidden element of the this pointer points
to a table of function pointers.

In C++ we would write

class line
{
public:
   virtual void pt(double t, double *x, double *y) = 0;
   virtual double len(void) = 0;
};

class straightline : public line
{
  // here we would define all the methods
};

Then we would have a spaceship object

class spaceship
{
 public:
   void move(line *path)
   {
      double i;
      double x;
      double y;

      for(i=0;i<=path->len();i++)
      {
         line->pt(i/path->len(), &x, &y);
         drawat(x, y);
         /* do rest of your display work */
      }
   }
};

In C, what we are doing is making explicit all the bookkeeping work that C++
does for us automatically. The void * for instance is the this pointer.


0
Malcolm
8/7/2003 9:48:03 PM
Reply: