简体   繁体   中英

Polymorphic behavior without using virtual functions

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.

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.

Instead of inheritance why not use a look up table (array) of function pointers? The following code is a quick & dirty pseudo code and probably won't compile, but should give you the general idea.

  enum Functions
  {
     Func1 = 0,
     Func2 = 1  
  };

  void *FunctionPointers[] = { &Function1, &Function2 };


  FunctionPointers[Func1]( some_parameter);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM