指向与对象类型不兼容的成员类型的指针→原因是什么?

时间:2018-11-04 14:38:49

标签: c++ function-pointers poco-libraries

最近我遇到了这样的编译器(GNU g ++ 4.9.2)错误:

ProceduralTimerTaskAdapter.cpp:25:13: error: pointer to member type ‘void (Poco::Util::Timer::)(Poco::Util::TimerTask&)’ incompatible with object type ‘Poco::Util::ProceduralTimerTaskAdapter’

这是相关的代码(除了必要的Poco库外,它几乎是独立的):

ProceduralTimerTaskAdapter.h:

#include <Poco/Util/Timer.h>
#include <Poco/Util/TimerTask.h>
#include <Poco/Util/TimerTaskAdapter.h>

#ifndef PROCEDURALTIMERTASKADAPTER_H
#define PROCEDURALTIMERTASKADAPTER_H

using namespace std;
using namespace Poco::Util;

typedef void (*Callback) (TimerTask&);

namespace Poco {
  namespace Util {
    class ProceduralTimerTaskAdapter : public TimerTaskAdapter <Timer> {
    public:
      ProceduralTimerTaskAdapter (Callback procedure); // Constructor

      void run (); // Method defining the main thread
    protected:
      ~ProceduralTimerTaskAdapter (); // Destructor (not for general use)
    private:
      ProceduralTimerTaskAdapter (); // Default constructor (not for general use)

      Callback procedure; // The callback procedure called by the timer.
    };
  }
}

#endif

ProceduralTimerTaskAdapter.cpp:

// This is the implementation of the ProceduralTimerTaskAdapter class.

#include <iostream>
#include <Poco/Util/Timer.h>
#include <Poco/Util/TimerTask.h>
#include <Poco/Util/TimerTaskAdapter.h>
#include "ProceduralTimerTaskAdapter.h"

using namespace std;
using namespace Poco::Util;

ProceduralTimerTaskAdapter::ProceduralTimerTaskAdapter (Callback procedure) : TimerTaskAdapter<Timer>::TimerTaskAdapter (*(new Timer ()), procedure)
{
  this -> procedure = procedure;
}

ProceduralTimerTaskAdapter::~ProceduralTimerTaskAdapter ()
{
}

void ProceduralTimerTaskAdapter::run ()
{
  TimerTask &task = *this;

  (this ->* procedure) (task);
}

事实上,我想做的是构建著名的TimerTaskAdapter的扩展来处理回调函数,这些函数绑定到特定的类(因为它们位于例如main.cpp中)。我用一个非常简单的自制方法覆盖了虚拟方法run (),该方法调用了回调。处理了几种不同的错误后,我最终遇到了这种明显的类不匹配问题,无法解决自己的问题。我什至不明白为什么编译器会声明一个类名,其名称为Poco::Util::Timer::(为什么以::结尾?)。由于ProceduralTimerTaskAdapter定义了一个名为procedure的成员,为什么编译器会期望另一个类?

谢谢。

2 个答案:

答案 0 :(得分:0)

Poco::Util::TimerTask派生(就像在Poco::Util::TimerTaskAdapter类中一样)并重写run方法,您将在其中调用过程。

class ProcedureAdapter : public Poco::Util::TimerTask {
public:

    typedef void (*Callback)(TimerTask&);

    ProcedureAdapter (Callback c) : callback(c) {;}

    void run () {
        callback(*this); // call some procedure which takes TimerTask
    }

    Callback callback;
};

void fun (Poco::Util::TimerTask&) {
    cout << "fun was invoked" << endl;
}

void fun2 (Poco::Util::TimerTask&) {
    cout << "fun2 was invoked" << endl; 
}

int main()
{
    Poco::Util::Timer t;
    t.schedule (new ProcedureAdapter{&fun},1,1);
    t.schedule (new ProcedureAdapter{&fun2},1,1);

答案 1 :(得分:0)

语法->*需要指向类对象的类型指针的左手操作符(例如this)和指向该类的成员函数的类型指针的右手操作符。但是在

TimerTask &task = *this;          // line 24
(this ->* procedure) (task);      // line 25

procedure不是指向ProceduralTimerTaskAdapter成员函数的指针。因此,您的代码格式错误。 procedure只是指向一个免费(非成员)函数的指针,该函数采用TimerTask&并返回void如果ProceduralTimerTaskAdapter来自 TimerTask ,则应编译以下代码

TimerTask &task = *this;
(this -> procedure) (task);

或更短

procedure(*this);

利用指向函数的指针可以像函数一样使用语法的事实。


编辑。从您的注释到另一个答案,您的代码似乎以另一种方式格式不正确,即ProceduralTimerTaskAdapter并非源自TimerTask。然后,当然第24行(而不仅仅是25行)应该会产生错误。因此,您似乎没有向我们显示与创建错误消息的代码完全相同的代码,或者不是向我们显示了由错误导致的所有错误。