【问题标题】:Store Pointer to Derived Class Function in Base Class [duplicate]在基类中存储指向派生类函数的指针
【发布时间】:2018-10-11 21:32:42
【问题描述】:

我想创建一个方法schedule_function,它将指向BasicAlgo 对象的成员函数的指针保存到ScheduledEvent,但没有在BasicAlgo 的父类Strategy 中定义所述函数.现在我正在使用这种方法,它可以很好地保存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));
}}

我尝试将Strategy::*func 替换为Strategy*::*func,但这会导致编译器错误并且看起来不正确。

有没有办法将派生类BaseAlgo中的成员函数的指针作为参数基类Strategy中,而不在Strategy中定义函数?

【问题讨论】:

标签: c++ pointers inheritance polymorphism member


【解决方案1】:

您无法将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);
}

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

【讨论】:

  • 这看起来很有希望——但是,在 schedule_function 的实现(.cpp 文件)中,它不允许我将参数更改为void (T::*func)()。在标题声明中使用void (T::*func)() 时,我是否使用void (Strategy::*func)() 保持相同的方式?
  • @EvanKirkiles 如果您想在多个翻译单元中使用模板,您需要将函数定义放入标题中。
【解决方案2】:

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

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

class Strategy {
    ...
    void schedule_function(function<void(Strategy*)> func) {
        heap_eventlist.emplace_back(std::make_unique<ScheduledEvent>(func));
    }
}; 

然后您可以直接使用 Strategy 的成员函数:

BasicAlgo g;
g.schedule_function (&BasicAlgo::f);   // f is a member function of Strategy

但您也可以提供任何其他接受策略指针作为参数的函数。如果您的 Strategy 是一个多态类,那么您可以尝试安全地向下转换 Strategy 指针并调用派生类的成员函数。

g.schedule_function ([](Strategy *x)->void {
                       BasicAlgo*b=dynamic_cast<BasicAlgo*>(x); 
                       if (b) b->ff(); 
                    });

这里是demo

【讨论】:

  • +1 也是很好的解决方案!但是,我试图让 schedule_function 易于为其他人实现,并且这些 lambdas 使用起来比 user207 的答案更复杂。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-18
  • 2012-12-26
相关资源
最近更新 更多