C++ 在基类中存储指向派生类函数的指针

C++ 在基类中存储指向派生类函数的指针,c++,pointers,inheritance,polymorphism,member,C++,Pointers,Inheritance,Polymorphism,Member,我想创建一个方法schedule\u function,它将指向BasicAlgo对象的成员函数的指针保存到ScheduledEvent中,但没有在BasicAlgo的父类Strategy中定义该函数。目前,我使用的方法适用于保存策略中的函数,但不适用于BasicAlgo函数: class Strategy { schedule_function(void (Strategy::*func)()) { // Puts the scheduled event built with the

我想创建一个方法
schedule\u function
,它将指向
BasicAlgo
对象的成员函数的指针保存到
ScheduledEvent
中,但没有在
BasicAlgo
的父类
Strategy
中定义该函数。目前,我使用的方法适用于保存
策略中的函数,但不适用于
BasicAlgo
函数:

class Strategy {

schedule_function(void (Strategy::*func)()) {
    // Puts the scheduled event built with the strategy function onto a list
    heap_eventlist.emplace_back(std::make_unique<events::ScheduledEvent>(func));
}}
类策略{
附表功能(无效(策略::*func)(){
//将使用strategy函数生成的计划事件放入列表中
heap_eventlist.emplace_back(std::make_unique(func));
}}
我尝试用
Strategy*::*func
替换
Strategy*:*func
,但这导致了编译器错误,而且似乎不正确


有没有办法将派生类
BaseAlgo
的成员函数指针作为基类
策略
中的参数,如果不在
Strategy

中定义函数,则无法将
BaseAlgo
的成员函数存储在指向
Strategy
的成员函数的指针中

您可以将
BaseAlgo
的成员函数存储在
BaseAlgo
的成员函数指针中,并且您可以将此类指针类型与CRTP一起使用:

template<class T>
struct Strategy {
    void schedule_function(void (T::*func)());
};

struct BasicAlgo : Strategy<BasicAlgo> {
    void memfun();
};

int main() {
    BasicAlgo b;
    b.schedule_function(&BasicAlgo::memfun);
}
模板
结构策略{
void调度函数(void(T::*func)();
};
基本结构:战略{
void memfun();
};
int main(){
基本b;
b、 日程安排功能(基本GO::memfun);
}


否则,您可以使用类型擦除函数包装器,例如
std::function
,而不是函数指针。

不可能将派生类函数指针存储在基类函数指针中

另一种方法是使用
策略*
参数存储函数:

class Strategy {
    ...
    void schedule_function(function<void(Strategy*)> func) {
        heap_eventlist.emplace_back(std::make_unique<ScheduledEvent>(func));
    }
}; 
但您也可以提供接受策略指针作为参数的任何其他函数。如果策略是多态类,则可以尝试安全地向下转换
策略
指针,并调用派生类的成员函数

g.schedule_function ([](Strategy *x)->void {
                       BasicAlgo*b=dynamic_cast<BasicAlgo*>(x); 
                       if (b) b->ff(); 
                    });
g.schedule\u函数([](策略*x)->void{
基本GO*b=动态_铸造(x);
如果(b)b->ff();
});

这里有一个

这看起来很有希望–但是,在schedule_函数的实现(.cpp文件)中,它不允许我将参数更改为
void(t::*func)(
)。在标题声明中使用
void(策略::*func)(
)时,我是否保持使用
void(策略::*func)(
)的方式相同?@EvanKirkiles如果您想在多个翻译单元中使用模板,您需要将函数定义放入标题中。+1也是一个很好的解决方案!然而,我试图让schedule_函数易于为其他人实现,而且这些lambda的使用比user207的答案要复杂一些
g.schedule_function ([](Strategy *x)->void {
                       BasicAlgo*b=dynamic_cast<BasicAlgo*>(x); 
                       if (b) b->ff(); 
                    });