Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphic behavior without using virtual functions

Tags:

c++

c

oop

I am working on a toy language for a microcontroller, I have a Function class that has 11 virtual methods, called "call" from no argument to 10 arguments all taking a base object class and returning a object class (function also extends object). When ever there is function definition in my language I define a class that extends Function class and implements one of the virtual methods depending on its args. Whenever I wanna call a function I just cast it to a Function* and call its call method with its arguments which works. so I got something like the following,



class object {}

//other types that extend object

class Function : public object{
   virtual object* call(){}
   virtual object* call(Object* a){}
   //....
}

//
// then during code generation I define
//

class s243 : public Function{
  Object* call(){
  //do somthig
  }
}


Now AFAIK for each class that extends function there will be a virtual function table, and each instance will have a pointer to that table, microcontroller I am doing this for only has 2kb of memory and I am going to have 50 60 functions at least to do basic stuff, so I am looking for ways to avoid using virtual functions. base class also defines a single virtual function that takes a deep copy of itself which is used by containers to copy the object without casting it to a particular type.

EDIT: I have code space lots I can trade code space for ram. As for function pointers, a function object can hold pointers to its state,

(define make-adder 
  (lambda (n)
    (lambda (x) (+ x n))))

An example from 90 min scheme compiler, I can pass a pointer to n so when ever it is returning a Function it knows what n is.

like image 660
Hamza Yerlikaya Avatar asked Nov 15 '22 00:11

Hamza Yerlikaya


1 Answers

A problem with your approach is that the base class provides a contract that implies every possible function signature is valid for every possible function. The user of a "Function" doesn't know which signature is valid for a given instance of a Function. Do they do

   virtual object* call()

or

   virtual object* call(Object* a)

At least with a function pointer or a boost::function you could specify the signature that should be expected:

   void object* (*funcPtr)(Object*);

   boost::function< object* (Object*) > boostFunc;

If you want to be able to call any function no matter what, you can use boost::bind to convert any function to a function of the signature above. Then you could easily store these functions in a container and do with them what you wish.

You'd also be wasting cycles with your implementation because of all the calls to functions that didn't do anything. The compiler may not be able to optimize this out due to the run time polymorphism involved.

like image 134
Doug T. Avatar answered Dec 22 '22 07:12

Doug T.