[ Home  |  FAQ-Related Q&As  |  General Q&As  |  Answered Questions ]


    Search the Q&A Archives


...implement virtual function concept in c?

<< Back to: Available C++ Libraries FAQ

Question by nannak aradnus
Submitted on 3/4/2004
Related FAQ: Available C++ Libraries FAQ
Rating: Rate this question: Vote
how to implement  virtual function concept in c?


Answer by koti
Submitted on 6/9/2004
Rating:  Rate this answer: Vote
What are Virtual Functions? How to implement virtual functions in "C"

 

Answer by fckrslut
Submitted on 9/21/2004
Rating: Not yet rated Rate this answer: Vote
how can we do this

 

Answer by foo
Submitted on 10/26/2004
Rating: Not yet rated Rate this answer: Vote
i'dlike to know as well

 

Answer by abdulla
Submitted on 12/21/2004
Rating: Not yet rated Rate this answer: Vote
virtual functions in C can be created by adding a pointer to function in a structure

 

Answer by Rajan Sharma (rajan_hp@yahoo.com)
Submitted on 12/28/2004
Rating: Not yet rated Rate this answer: Vote
By default, C++ matches a function call with the correct function definition at compile time. This is called static binding. You can specify that the compiler match a function call with the correct function definition at run time; this is called dynamic binding. You declare a function with the keyword virtual if you want the compiler to use dynamic binding for that specific function. A virtual function cannot be global or static because, by definition, a virtual function is a member function of a base class and relies on a specific object to determine which implementation of the function is called. You can declare a virtual function to be a friend of another class.



From the C++ class

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

a C code fragment can be derived. The three C++ member functions of class A are rewritten using out-of-line (standalone) code and collected by address into a struct named A_functable. The data members of A and combined with the function table into a C struct named 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));
}


 

Answer by nickname
Submitted on 6/10/2005
Rating: Not yet rated Rate this answer: Vote
no i need answer only because i am fresher

 

Answer by pankaj
Submitted on 7/2/2005
Rating: Not yet rated Rate this answer: Vote
A Virtual Function is a function that can be overridden in its subclass by specialized implementations.

 

Answer by farheen
Submitted on 12/8/2005
Rating: Not yet rated Rate this answer: Vote
tell me

 

Answer by Hello
Submitted on 12/30/2005
Rating: Not yet rated Rate this answer: Vote
typedef int (*VirtualFunctionPointer)();

struct VTable
{
   // d and i fields are used when multiple inheritance and virtual
   // base classes are involved. We will be ignoring them for this
   // discussion.
   int d;
   int i;
   // A function pointer to the virtual function to be called is
   // stored here.
   VirtualFunctionPointer pFunc;
};

struct Shape
{
  int m_x;
  int m_y;
  
  // The C++ compiler inserts an extra pointer to a vtable which
  // will keep a function pointer to the virtual function that
  // should be called.
  VTable *pVTable;
};

struct Circle
{
   // Fields inherited from Shape
   int m_x;
   int m_y;
   VTable *pVTable;
  
   // Fields added by Circle
   int m_radius;
};

// The Shape vtable array contains entries for Draw and MoveTo
// virtual functions. Notice that there is no entry for Erase,
// as it is not virtual. Also, the first two fields for every
// vtable entry are zero, these fields might have non zero
// values with multiple inheritance, virtual base classes
// A third entry has also been defined for the virtual destructor

VTable VtableArrayForShape[] =
{
    // Vtable entry virtual function Draw.
    // Since Draw is pure virtual, this entry
    // should never be invoked, so call error handler
    { 0, 0, pure_virtual_called_error_handler },

    // This vtable entry invokes the base class's
    // MoveTo method    
    { 0, 0, Shape_MoveTo },
    
    // Entry for the virtual destructor
    { 0, 0, Shape_Destructor }
};

// Vtable array for Circle

VTable VtableArrayForCircle[] =
{
    // Vtable entry virtual function Draw.
    // Circle_Draw method will be invoked when Shape's
    // Draw method is invoked
    { 0, 0, Circle_Draw },

    // This vtable entry invokes the base class's
    // MoveTo method    
    { 0, 0, Shape_MoveTo },
    
    // Entry for the virtual destructor
    { 0, 0, Circle_Destructor }
};

Shape *Shape_Constructor(Shape *this, int x, int y)
{
  //Check if memory has been allocated for struct Shape.
  if (this == NULL)
  {
    //Allocate memory of size Shape.
    this = malloc(sizeof(Shape));
  }
  
  //Once the memory has been allocated for Shape, initialise members of Shape.
  if (this)
  {  
     // Initialize the VTable pointer to point to shape
     this->pVTable = VTableArrayForShape;
     this->m_x = x;
     this->m_y = y;
  }
  
  return this;
}

void Shape_Destructor(Shape *this, bool dynamic)
{
  // Restore the VTable to that for Shape. This is
  // required so that the destructor does not invoke
  // a virtual function defined by a inheriting class.
  // (The base class destructor is invoked after inheriting
  // class actions have been completed. Thus it is not
  // safe to invoke the ineriting class methods from the
  // base class destructor)
  this->pVTable = VTableArrayForShape;
  
  . . .
  
  //If the memory was dynamically allocated for Shape, explicitly free it.
  if (dynamic)
  {
    free(this);
  }
}

Circle *Circle_Constructor(Circle *this, int x, int y, int radius)
{
  //Check if memory has been allocated for struct Circle.
  if (this == NULL)
  {
    //Allocate memory of size Circle.
    this = malloc(sizeof(Circle));
  }
  
  //Once the memory has been allocated for Circle, initialise members of Circle.
  if (this)
  {
      // Invoking the base class constructor
      Shape_constructor((Shape *)this, x, y);
      this->pVtable = VtableArrayForCircle;
      
      this->m_radius = radius;
  }
  return this;
}

void Circle_Destructor(Circle *this, bool dynamic)
{
  // Restore the VTable to that for Circle
  this->pVTable = VTableArrayForCircle;
  
  . . .
  
  // Invoke the base class destructor after ineriting class
  // destructor actions have been completed. Also note that
  // that the dynamic flag is set to false so that the shape
  // destructor does not free any memory)
  Shape_Destructor((Shape *) this, false);
  
  //If the memory was dynamically allocated for Circle, explicitly free it.
  if (dynamic)
  {
    free(this);
  }
}

void Circle_Draw(Circle *this)
{
   glib_draw_circle(this->m_x, this->m_y, this->m_radius);
}

main()
{    
  //Dynamically allocate memory by passing NULL in this arguement.
  //Also initialse members of struct pointed to by pShape.
  Shape *pShape = Circle_Constructor(NULL, 50, 100, 25);

  //Define a local variable aCircle of type struct Circle.
  Circle aCircle;
  
  //Initialise members of struct variable aCircle.
  Circle_Constructor(&aCircle, 5, 5, 2);
  
  // Virtual function Draw is called for the shape pointer. The compiler
  // has allocated 0 offset array entry to the Draw virtual function.
  // This code corresponds to "pShape->Draw();"
  (pShape->pVTable[0].pFunc)(pShape);
  
  // Virtual function MoveTo is called for the shape pointer. The compiler
  // has allocared 1 offset array entry to the MoveTo virtual function.
  // This code corresponds to "pShape->MoveTo(100, 100);"
  (pShape->pVTable[1].pFunc)(pShape, 100, 100);

  // The following code represents the Erase method. This method is
  // not virtual and it is only defined in the base class. Thus
  // the Shape_Erase C function is called
  Shape_Erase(pShape);
  
  // Delete memory pointed to by pShape (explicit delete in original code).
  // Since the destructor is declared virtual, the compiler has allocated
  // 2 offset entry to the virtual destructor
  // This code corresponds to "delete pShape;"
  (pShape->pVTable[2].pFunc)(pShape, true);

  // The following code corresponds to aCircle.Draw().
  // Here the compiler can invoke the method directly instead of
  // going through the vtable, since the type of aCircle is fully
  // known. (This is very much compiler dependent. Dumb compilers will
  // still invoke the method through the vtable)
  Circle_Draw(&aCircle);
  
  //Since memory was allocated from the stack for local struct  
  //variable aCircle, it will be deallocated when aCircle goes out of scope.
  // The destructor will also be invoked. Notice that dynamic flag is set to
  // false so that the destructor does not try to free memory. Again, the
  // compiler does not need to go through the vtable to invoke the destructor.
  Circle_Destructor(&a, false);
}
      

 

Answer by sam_tam
Submitted on 3/1/2006
Rating: Not yet rated Rate this answer: Vote
where can i find the answer

 

Answer by Lipun
Submitted on 3/15/2006
Rating: Not yet rated Rate this answer: Vote
Virtual Function can be implemented in C.
By Using Function Pointer
with varible no. of arguments.
void fun1(){}
void fun2() {}
void main()
{
  void fun1();
   void fun2();
void (*fun[2])()= {& fun1, & fun2};
}
I was not clear about the answer, I just got some info about this answer. Please check and  tell me about the answer.

 

Answer by Bhabani
Submitted on 5/8/2006
Rating: Not yet rated Rate this answer: Vote
How implement virtual function in C.

// C++ example

struct MyClass // remember, in C++ a struct is a class that defaults to
public.
{
   long _iID;
   char _strLabel[16];

   MyClass(long iID) : _iID(iID)
   {
       memset(_strLabel, 0, sizeof _strLabel);
   }
   virtual bool doSomething();
};

bool MyClass::doSomething()
{
   printf("ID = %ld Label = %-*.*s\n",
       _iID, sizeof(_strLabel), sizeof(_strLabel), _strLabel);  
}

/*
   C example with data member that is a function pointer used to
simulate a virtual method.
    Notice how much more verbose the C example is compared to the C++
example above.
*/

#include <stdio.h>

struct MyClass
{
   long _iID;
   char _strLabel[16];

   /* sorry, no constructor here but see below!! */
   bool (*_pDoSomething)(struct MyClass *pThis);
};

extern struct MyClass *newInstance();

/*
   code for C version of a virtual method. C doesn't have a "this"
pointer so
   we have to explicitly create one here.
*/
static bool doSomething(struct MyClass *pThis)
{
   printf("ID = %ld Label = %-*.*s\n",
       pThis->_iID, sizeof(pThis->_strLabel), sizeof(pThis->_strLabel),
pThis->_strLabel);
}

// C equivalent to a constructor

struct MyClass *newInstance(long iID)
{
   struct MyClass *pClass = (struct MyClass *)malloc(sizeof (MyClass) );
   if (pClass)
   {
       pClass->_iID = iID;
       memset(pClass->_strLabel, 0, sizeof pClass->_strLabel);
       // assign virtual method.
       pClass->_pDoSomething = doSomething;
   }
   return pClass;
}

/* typical usage for C class above ... */
int main(int argc, char *argv[])
{
   /* constructor called to create / initialize instance. */
   MyClass *pClass = newInstance(100);
   if (pClass)
   {
       strcnpy(pClass->_strLabel, "Howdy folks.",
sizeof(pClass->_strLabel));
       pClass->_pDoSomething();
       /* ... and here's a non-virtual method call. */
       doSomething(pClass);
       /* (non-virtual) destructor call. */
       free(pClass);
   }
   return 0;
}



 

Answer by Rainier
Submitted on 9/6/2006
Rating: Not yet rated Rate this answer: Vote
by using function pointer to construct a virtual function table

 

Answer by Andy
Submitted on 5/28/2007
Rating: Not yet rated Rate this answer: Vote
Use function pointers. Typedef your function pointer according to data at runtime and call that function pointer when u need to.

 

Your answer will be published for anyone to see and rate.  Your answer will not be displayed immediately.  If you'd like to get expert points and benefit from positive ratings, please create a new account or login into an existing account below.


Your name or nickname:
If you'd like to create a new account or access your existing account, put in your password here:
Your answer:

FAQS.ORG reserves the right to edit your answer as to improve its clarity.  By submitting your answer you authorize FAQS.ORG to publish your answer on the WWW without any restrictions. You agree to hold harmless and indemnify FAQS.ORG against any claims, costs, or damages resulting from publishing your answer.

 

FAQS.ORG makes no guarantees as to the accuracy of the posts. Each post is the personal opinion of the poster. These posts are not intended to substitute for medical, tax, legal, investment, accounting, or other professional advice. FAQS.ORG does not endorse any opinion or any product or service mentioned mentioned in these posts.

 

<< Back to: Available C++ Libraries FAQ


[ Home  |  FAQ-Related Q&As  |  General Q&As  |  Answered Questions ]

© 2008 FAQS.ORG. All rights reserved.