简体   繁体   English

不使用虚函数的多态行为

[英]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). 我正在研究微控制器的玩具语言,我有一个Function类,它有11个虚拟方法,从无参数调用“call”到10个参数,所有参数都采用基础对象类并返回一个对象类(函数也扩展了对象)。 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. 当我的语言中有函数定义时,我定义了一个扩展Function类的类,并根据其args实现一个虚方法。 Whenever I wanna call a function I just cast it to a Function* and call its call method with its arguments which works. 每当我想调用一个函数时,我只需将其转换为Function *并使用其参数调用其调用方法。 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. 现在扩展函数的每个类的AFAIK将有一个虚函数表,每个实例都有一个指向该表的指针,我正在做的这个微控制器只有2kb的内存,我将至少有50个60函数做基本的东西,所以我正在寻找避免使用虚函数的方法。 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. 编辑:我有代码空间很多我可以为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. 从90分钟方案编译器的一个例子,我可以传递一个指向n的指针,所以当它返回一个函数时,它知道n是什么。

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: 至少使用函数指针或boost ::函数,您可以指定应该预期的签名:

   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. 如果你想能够调用任何函数,无论如何,你可以使用boost :: bind将任何函数转换为上面签名的函数。 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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