从基类调用派生类中的函数

Posted

技术标签:

【中文标题】从基类调用派生类中的函数【英文标题】:Call function in derived class from base class 【发布时间】:2021-08-17 00:38:16 【问题描述】:

我有一个计时器类,当计时器经过时,将调用 TimeEventHdlr。如果提供了回调函数,那么它将调用,否则将调用类中的函数。当计时器经过时调用派生类函数有什么更好的解决方案?

typedef void(*TimerCallback)();

struct Parm 
    TimerCallback clbk;
;

class TimerHdlr 
    TimerHdlr(Parm &parm);
    timer_t mTimerId;
    TimerCallback mTimerClbk;
    void StartTimer();
    void TimerFunc();
    static void TimeEventHdlr(sigval_t sigVal);
;

TimerHdlr::TimerHdlr(Parm &parm) : mTimerClbk(parm.clbk) 
    struct sigevent sigev;
    memset(&sigev, 0, sizeof(struct sigevent));
    sigev.sigev_value.sival_ptr = (void *)this;
    sigev.sigev_notify = SIGEV_THREAD;
    sigev.sigev_notify_function = &TimerHdlr::TimeEventHdlr;
    timer_create(CLOCK_REALTIME, &sigev, &mTimerId);


void TimerHdlr::StartTimer() 
    struct itimerspec timerSpec;
    timerSpec.it_interval.tv_sec = 0; /* oneshot timer */
    timerSpec.it_interval.tv_nsec = 0;
    timerSpec.it_value.tv_sec = 10;
    timerSpec.it_value.tv_nsec = 0;
    timer_settime(mTimerId, 0, &timerSpec, NULL);


void TimerHdlr::TimerFunc() 

/*static*/ void TimerHdlr::TimeEventHdlr(sigval_t val) 
    TimerHdlr *obj = static_cast<TimerHdlr*>(val.sival_ptr);
    if (obj->mTimerClbk == nullptr)
        obj->TimerFunc();
    else
        obj->mTimerClbk();

派生类实现:

class DerivedTimer: public TimerHdlr 
    static void TimeoutClbkHdlr(); 
;

Parm parm = .clbk = DerivedTimer::TimeoutClbkHdlr;

DerivedTimer::DerivedTimer() : TimerHdlr(parm) 


/*static*/ void DerivedTimer::TimeoutClbkHdlr() 
// function to called when base timer elapses

【问题讨论】:

你知道virtual functions吗? 【参考方案1】:

TimerHdlr 中将TimerFunc() 设为virtual,然后在DerivedTimer 中覆盖它。 DerivedTimer 中不需要静态的 TimeoutClbkHdlr 方法。

typedef void(*TimerCallback)();

class TimerHdlr 
private:
    timer_t mTimerId;
    TimerCallback mTimerClbk;
    static void TimeEventHdlr(sigval_t sigVal);
protected:
    virtual void TimerFunc();
public:
    TimerHdlr(TimerCallback clbk = nullptr);
    void StartTimer();
;

TimerHdlr::TimerHdlr(TimerCallback clbk) : mTimerClbk(clbk) 
    struct sigevent sigev;
    memset(&sigev, 0, sizeof(struct sigevent));
    sigev.sigev_value.sival_ptr = (void *)this;
    sigev.sigev_notify = SIGEV_THREAD;
    sigev.sigev_notify_function = &TimerHdlr::TimeEventHdlr;
    timer_create(CLOCK_REALTIME, &sigev, &mTimerId);


void TimerHdlr::StartTimer() 
    struct itimerspec timerSpec;
    timerSpec.it_interval.tv_sec = 0; /* oneshot timer */
    timerSpec.it_interval.tv_nsec = 0;
    timerSpec.it_value.tv_sec = 10;
    timerSpec.it_value.tv_nsec = 0;
    timer_settime(mTimerId, 0, &timerSpec, NULL);


void TimerHdlr::TimerFunc() 

/*static*/ void TimerHdlr::TimeEventHdlr(sigval_t val) 
    TimerHdlr *obj = static_cast<TimerHdlr*>(val.sival_ptr);
    if (obj->mTimerClbk == nullptr)
        obj->TimerFunc();
    else
        obj->mTimerClbk();

class DerivedTimer: public TimerHdlr 
protected:
    void TimerFunc() override;
public:
    DerivedTimer();
;

DerivedTimer::DerivedTimer() : TimerHdlr() 


void DerivedTimer::TimerFunc() 
    // function to called when base timer elapses

【讨论】:

以上是关于从基类调用派生类中的函数的主要内容,如果未能解决你的问题,请参考以下文章

从基类c ++的向量中的派生类调用虚拟方法[重复]

派生类不从基类继承重载方法

从基类函数派生的类容器

如何从基类调用派生类函数?

如何从基类调用派生赋值运算符?

从基类派生类中 C++ 向量的可访问性