每个实例的自定义函数(C ++)

时间:2018-06-07 19:44:14

标签: c++ function scripting

我有一个“EngineObject”类

我想为该类设置一个自定义函数,该函数可能因该对象的实例而异。

现在我正在使用像这样的函数指针:

class EngineObject{
    public:
    bool (*Update)(EngineObject* Me);
    bool (*Prep)(EngineObject* Me);
    bool (*OnCollide)(EngineObject* Me, EngineObject* Them);
};

你可能已经注意到,这要求我做一些非常残暴的事情。我必须将对象提供给其成员函数... Digusting

它还要求我编写额外的getter和setter,我真的不想从代码的任何其他部分访问,只是这样我可以通过函数指针传入的函数中看到EngineObject的“内部”

我是否有某种方法可以编写一个我可以应用的函数,每个对象的实例,可以访问对象的私有,而不必将对象传递给函数?

为了清晰度: 假设我想要两个EngineObjects

EngineObject1 = new EngineObject();
EngineObject2 = new EngineObject();

我想将更新函数1设置为(某事物),将2设置为(别的)

EngineObject1.Update = &foo;
EngineObject2.Update = &bar;

我不能简单地使用虚函数和继承,因为这些函数需要能够在运行时分配和重新分配。

问题在于我需要从这些函数访问私有,为了做到这一点,我需要为所有东西编写公共getter和setter,这样就消除了制作任何私有的需要......

上下文:

我这样做的原因是允许在运行时生成动态类型而不进行内省,以最大化从脚本接口可以完成的任务,并减少需要绑定到脚本接口的函数总数和减少用户的学习曲线。

基本上,你有一个EngineObjectTemplate类,它为这个动态生成的类型指定了所有这些函数,然后使用EngineObjectTemplate类中的函数创建EngineObject

可以通过组合各种预先编写的C ++函数(Update,Prep,OnCollide)在运行时生成EngineObjectTemplates。这将是一种“类型”。

如果用户希望编写新的更新,准备或oncollide函数,他们可以选择将其编写并编译成DLL文件并将其添加到项目中(我的EXE将读取并添加到函数列表中)指针,可以通过脚本语言中的字符串名称引用以分配给模板和/或引擎对象),或者它们可以用我选择的脚本语言编写脚本,这当然会慢一些。

我这样做的另一个原因是我想避免继承,因为HELL使继承的类与我计划使用的脚本包装器一起工作。

2 个答案:

答案 0 :(得分:0)

您想要做的事情是不可能的,因为您实际上要求的基本上是:

"我如何让代码生活在一个类访问私有成员之外"。

如果没有跳过一些丑陋丑陋的箍,这是可能的,那就意味着private被打破了。

访问类的私有成员的唯一方法是该类显式允许您从其接口访问它们,或者将代码标记为friend作为其声明的一部分。

要么成员是私人的,要么不是。你无法双管齐下。

N.B。这是一个谎言的,因为你可以在一些特殊的角落案例中做一些技巧,但这些只能用作最后的手段。

答案 1 :(得分:-1)

您可以创建一个覆盖() operator的可调用对象类。基类将为可替换函数作为参数接收实现该特定方法的子类提供模板。然后将可调用类声明为您所属类的friend。如下所示:

class EngineObject;
class Callable;

class EngineObject
{
private:
  int member;
  Callable *func;

public:
  EngineObject(int m, Callable *f) : member(m), func(f) {}

  int Call(int p)
  {
    return func(p);
  }

  friend Callable;
};

class Callable;
{
public:
  int operator(EngineObject *eo, int param)
  {
    eo->member = param;
    return param;
  }
};

在上面,我还进一步隐藏了包装器后面的变量函数调用,以便外部函数也不需要将对象作为参数传递。