如何扩展功能

时间:2017-09-03 16:27:24

标签: c++ function oop

现代C ++中是否有一种“扩展”功能的方法? 也许这个伪代码可以解释我想要的东西:

extendable void foo()
{
   doSomething();
}

extend foo()
{
   moo();
}

编译时,函数foo()应该这样做:

foo()
{
    doSomething();
    moo();
}

我以为我可以通过在foo()中将每个函数存储在函数指针的std :: vector中来实现这一点,foo()将循环遍历向量并运行所有函数。

但是,我需要在编译时执行此操作,因此无法运行vector.push_back()

我试图在#define指令的帮助下做到这一点,但我找不到解决方案。

提前感谢您的回答。

编辑:我的实际问题

我想实现某种Entity-Component-System,每个组件都有一个列表。每个实体都有一个ID,指向组件列表中的list元素。 因为我不想重复创建新类型组件的步骤,所以我想制作一个#define-directive,以便为我将创建的每个新组件自动生成它。

主要问题是如果创建了新实体,则向每个组件添加一个元素。 这是我想要的代码:

#define addComponent(name)                                          \
    struct name;                                                    \
private:                                                            \
    std::vector<name> name ## vector;                               \
public:                                                             \
    extend addEntity()                                              \
    {                                                               \
        struct name a;                                              \
        name ## vector.push_back(a);                                \
    }                                                               \
    void set ## name(const int & ID, name newName)                  \
    {                                                               \
        name ## vector[ID] = newName;                               \
    }                                                               \
    name get ## name(const int & ID)                                \
    {                                                               \
        return name ## vector[ID];                                  \
    }

class Component
{
public:
    Component();
    ~Component();

    extendable void addEntity(int * ID);

    addComponent(position)
    struct position
    {
        float x, y, z;
    }
};

2 个答案:

答案 0 :(得分:3)

  

我可以扩展功能吗?

没有

您描述的内容是不可能的。任何机制都不支持编译器生成一个函数,该函数将调用foo()在扩展之前调用的函数。

虚拟方法不起作用,因为它们提供的只是Polymorphism(希腊语中的许多形式)。

答案 1 :(得分:3)

您没有充分解释您的想法和原因(甚至编辑后)。对于成员函数,确实阅读了有关vtables的更多信息(实现dynamic dispatch的常用方法)。

请注意,功能可以是值(特别感谢lambda expressionsstd::function。)

然后,您可以使用std::dequeue声明函数的双端队列todoque(它可以是static变量或某些class的字段等。 ..)

 std::deque<std::function<void(void)>> todoque;

并扩展它,可能使用lambda,

 todoque.push_back([](void) { moo(); };

并使用

初始化它
  todoque{[](void){doSomething()}};

然后代码

 void foo() {
   for (auto f : todoque) f();
 }

我希望你明白了。

BTW,在上面的示例中,lambda可能不需要,您可能只需编写todoque.push_back(moo)

BTW我建议阅读SICP(不是关于C ++,而是关于一种名为Scheme的函数式编程语言),它是一个很好的(并且可以免费下载)编程的介绍。

  

我以为我可以通过在函数指针的std :: vector中存储我想要的foo()函数来实现这个目的

不,甚至更好,使它成为std::vector<std::function<void(void)>>并使用lambda表达式。

  

但是,我需要在编译时这样做,因此我无法运行vector.push_back()

为什么不呢?它可能发生在一些静态数据的构造函数中。

也许你的总体目标(你没有解释)也可能通过涉及JIT compiling的运行时元编程技术和运行时代码的生成来实现。您可以使用libgccjitLLVM等库;你也可以在一些临时文件中发出C ++代码,将其编译为插件,然后插入dlopen。另见this

关于您编辑的实体 - 组件 - 系统目标,您是否考虑编写一些适用于构建自动化系统规则的专用C ++代码生成器(或预处理器)(例如makeninja等。 ..)会在构建时明智地触发? Qt moc可能是鼓舞人心的。还可以考虑使用某些通用预处理器,如m4gpp