Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 不使用虚函数的多态行为_C++_C_Oop - Fatal编程技术网

C++ 不使用虚函数的多态行为

C++ 不使用虚函数的多态行为,c++,c,oop,C++,C,Oop,我正在为一个微控制器开发一种玩具语言,我有一个函数类,它有11个虚拟方法,称为“调用”,从没有参数到10个参数,所有这些参数都接受一个基本对象类并返回一个对象类(函数也扩展了对象)。当我的语言中有函数定义时,我会定义一个类来扩展函数类,并根据其参数实现一个虚拟方法。每当我想调用一个函数时,我就把它转换成一个函数*并用它的参数调用它的call方法。所以我得到了如下结果 class object {} //other types that extend object class Functi

我正在为一个微控制器开发一种玩具语言,我有一个函数类,它有11个虚拟方法,称为“调用”,从没有参数到10个参数,所有这些参数都接受一个基本对象类并返回一个对象类(函数也扩展了对象)。当我的语言中有函数定义时,我会定义一个类来扩展函数类,并根据其参数实现一个虚拟方法。每当我想调用一个函数时,我就把它转换成一个函数*并用它的参数调用它的call方法。所以我得到了如下结果



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
  }
}

现在,对于每个扩展函数的类,都会有一个虚拟函数表,每个实例都会有一个指向该表的指针,我这样做的微控制器只有2kb的内存,我至少会有50 60个函数来做基本的事情,所以我正在寻找避免使用虚拟函数的方法。基类还定义了一个虚拟函数,该函数获取自身的深层副本,容器使用该副本复制对象,而无需将其强制转换为特定类型

编辑:我有很多代码空间,我可以用代码空间换取ram。对于函数指针,函数对象可以保存指向其状态的指针

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

以90分钟scheme编译器为例,我可以传递一个指向n的指针,这样当它返回一个函数时,它就知道n是什么。

为什么不使用函数指针的查找表(数组)来代替继承?下面的代码是一个快速而肮脏的伪代码,可能不会编译,但应该会告诉您一般的想法

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

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


  FunctionPointers[Func1]( some_parameter);

您的方法的一个问题是基类提供了一个契约,该契约意味着每个可能的函数签名对每个可能的函数都有效。“函数”的用户不知道哪个签名对函数的给定实例有效。是吗

   virtual object* call()

至少可以使用函数指针或boost::函数指定预期的签名:

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

   boost::function< object* (Object*) > boostFunc;
void object*(*funcPtr)(object*);
boost::functionboostFunc;
如果您希望能够无论如何调用任何函数,可以使用boost::bind将任何函数转换为上述签名的函数。然后,您可以轻松地将这些函数存储在一个容器中,并根据需要使用它们


由于所有对函数的调用都没有做任何事情,因此在实现过程中也会浪费周期。由于涉及到运行时多态性,编译器可能无法对此进行优化。

为什么不使用函数指针呢?因为函数对象可以保存状态,它需要知道的状态(自由变量)是否在代码生成期间使用其构造函数设置?如果要避免使用虚拟函数,您是否考虑过使用CRTP?@tstenner,函数指针将占用与vtable指针相同的空间,因此不会有太多节省-只有vtable本身,每个类一个。所有函数的类型不同。每一个都有不同数量的参数。@nathan:这相当于使用vtable。因为代码是通过编程生成的,所以boost调用了正确的虚函数。它是一个只有32 kb代码空间的微控制器,它甚至没有标准stl,更不用说boost了。@Hamza,您可以在基类中使用一个“call”方法规范化为更少的虚拟函数,然后通过填写剩余参数将每个签名的子类重定向到内部函数指针。
   void object* (*funcPtr)(Object*);

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