C++ 我能简化一下吗?

C++ 我能简化一下吗?,c++,reference,polymorphism,function-pointers,C++,Reference,Polymorphism,Function Pointers,addFunction方法将函数添加到基类中的列表中, 然后可以枚举它来调用所有函数 有没有办法简化函数的添加(减少键入工作?我想,您可能会使加法运算符过载。您能解释一下这样做的目的是什么吗 这似乎是一个相当糟糕的设计,难道你不能有一个抽象类(“c++接口”),比如“Computable”,它有一个纯虚拟函数1,每个实现的子类Computable,然后让MyFunctionSet维护一组Computable吗 使用函数指针有什么特殊原因吗?看起来像是将指向派生类函数的成员函数指针指定给指向基类函

addFunction方法将函数添加到基类中的列表中,
然后可以枚举它来调用所有函数


有没有办法简化函数的添加(减少键入工作?

我想,您可能会使加法运算符过载。

您能解释一下这样做的目的是什么吗

这似乎是一个相当糟糕的设计,难道你不能有一个抽象类(“c++接口”),比如“Computable”,它有一个纯虚拟函数1,每个实现的子类Computable,然后让MyFunctionSet维护一组Computable吗


使用函数指针有什么特殊原因吗?

看起来像是将指向派生类函数的成员函数指针指定给指向基类函数的成员函数指针。这是被禁止的,因为这会在打字系统中打开一个漏洞。这让我大吃一惊(至少对我来说,这是我第一次听到这个消息)。阅读原因

要回答您的实际问题,我将制作
addFunction
模板:

typedef void (FunctionSet::* Function)();

class MyFunctionSet : public FunctionSet
{
protected:
    void addFunctions()
    {
        addFunction(Function(&MyFunctionSet::function1));
    }

    void function1()
    {
        // Do something.
    }
};
将基类中的
addFunction
更改为:

void addFunctions() {
    addFunction(&MyFunctionSet::function1);
}
模板
void addFunction(void(派生::*f)(){
myFunctions.push_back(静态_cast(f));
}

最好使用
static\u cast
,因为它会告诉您
Derived
是否实际上不是从
FunctionSet

派生的,所以我倾向于在某种程度上不同意Uri

如果您正在实现Observer模式,您希望能够说:

“当对象X执行Y时,我想执行代码Z”

使用纯粹基于抽象类的方法并不是最好的方法。要求每个事件处理程序都有一个单独的类(特别是在C++中)是过分的。如果你来自爪哇,他们就是这样做的。然而,Java有两个特性,这让它有点烦人:匿名类和“实例”成员类。这允许您为同一类中的多个事件定义多个处理程序。您必须在方法前面加上“class{”,但您可以这样做

C++既没有匿名类,也没有“实例”成员类。如果您有多个需要共享状态的处理程序,那么为事件使用抽象类会变得更加麻烦。您必须手动生成闭包,这可能会很快让人恼火

net使用委托来处理事件,这些处理基本上是类型安全的函数指针。它们使得处理事件的代码非常直接。与C++中的函数指针不同,委托将成员函数指针和静态函数指针统一起来。任何成员函数的参数,留下看起来像静态函数指针的函数指针。这意味着处理事件的对象的类型不是事件“接口”的一部分。这使得它非常灵活

不能直接使用C++成员函数指针来完成这一点,因为“这个”类型最终是函数指针类型的一部分,因此限制了处理程序只出现在当前类中。

< > C++的最佳解决方案是两个混合,你想要的是一个通用的接口:
template<typename Derived>
void addFunction(void(Derived::*f)()) {
    myFunctions.push_back(static_cast<Function>(f));
}
template <class T>
class MemberFuncEventHandler : public EventHandler
{
public:


    MemberFuncEventHandler(T * pThis, void (T::*pFunc)()) : m_pThis(pThis), m_pFunc(pFunc)
    {
    }

    void Handle()
    {
        (m_pThis->*m_pFunc)();
    } 
private:
    T* m_pThis;
    void (T::*m_pFunc)();
};

template <class T>
EventHandler * Handler(T * pThis, void (T::*pFunc)())
{
    return new MemberFuncEventHandler<T>(pThis, pFunc);
}
然后是这样的成员函数的实现

class EventHandler
{
public:
    virtual void Handle() = 0;
};

如果你想建立一个回调系统或者其他什么东西,我建议使用Boost.Signals库。基本上,它可以聚合函数并在命令上调用函数组(就像其他任何信号库一样),但它也可以与Boost.Bind和Boost.function一起使用,这两个函数都很棒

例如:

Handlers += Handler(obj, &(c1::foo));
Handlers += Handler(obj, &(c2::bar));
Handlers += Handler(blaa); // for static methods...
使用boost::function
使用boost::bind
使用boost::signal
使某些函数无效();
福阿;
b栏;
信号信号;
sig.connect(绑定(&Foo::Foo,&a));
sig.connect(绑定(&Bar::Bar,&b));
信号连接(一些其他功能);
sig();//调用->a.foo(),b.bar(),some_other_func()

还支持阻塞、复杂的连接管理和其他整洁的功能。

你能更改标题吗?当问题听起来很普通时,有时似乎是一个陷阱,让人们来看看(是的,我被困住了!)描述性问题标题更具可解性。至于实际答案,我想我需要复习一下我的C++;一些上下文会很好。你想解决的问题是什么?它将在哪里使用?嗯,你在一个答案的评论中说你想“保持高效”。。我认为我们需要更多地了解这一点,以便给您提供更好的答案。您可以存储函数对象,但也需要存储this指针。functor通常比函数指针更有效。但这是在没有虚拟函数的情况下实现的。在任何情况下,“创建类”这是胡说八道,而且没有任何开销。我觉得这听起来像是过早的优化。你到底在做什么,你对效率的关注超过了好的OO原则?动态绑定和手动管理你自己的函数指针一样高效。我想这是风格和实际项目的问题。函数指针我NC C++是危险的。如果你关心的是保存打字,使用一个更好的IDE或CASE工具。在我的一个工作中,我们把整个计算机系统表示成具有等级结构的小寄存器和指令格式,并且我们很高兴使用Rose来为我们做所有的繁琐工作。您不希望使用需要高于平均水平的编程才能理解和维护的语言功能。如果这是个人代码,情况就不同了。可能没有办法删除&或MyFunctionSet::parts?不,没有办法:/wait,我的意思是,如果您分配的指针没有大小写,那么这是禁止的。听起来好像您弄错了,我不想说你的代码被C++禁止了。抱歉,如果听起来有点不清楚:创建一个单独的类不是一个过激的术语。
using boost::function
using boost::bind
using boost::signal

void some_other_func();    

Foo a;
Bar b;

signal<void()> sig;

sig.connect(bind(&Foo::foo,&a));
sig.connect(bind(&Bar::bar,&b));
sig.connect(some_other_func);

sig(); // calls -> a.foo(), b.bar(), some_other_func()