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

Pointer to member type incompatible with object type → What is the cause?

最近我 运行 编译器 (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 的扩展来处理回调函数, 绑定到特定 class(因为它们位于 main.cpp,例如)。我用一个非常简单的自制方法覆盖了虚拟方法 run (),它调用回调。在处理了几个不同的错误之后,我最终遇到了我自己无法解决的明显 class 不匹配问题。我什至不明白为什么编译器声明一个 class 名称,其名称是 Poco::Util::Timer:: (为什么它以 :: 结尾?)。由于 ProceduralTimerTaskAdapter 定义了一个名为 procedure 的成员,为什么编译器需要另一个 class?

谢谢。

派生自 Poco::Util::TimerTask(如 Poco::Util::TimerTaskAdapter class)并重写 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);

语法 ->* 需要一个指向 class 对象(例如 this)的指针类型的左手运算符和一个指向 this 对象的指针类型的右手运算符class。但是在

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 行)应该会产生错误。因此,您似乎没有向我们展示与创建错误消息的代码完全相同的代码,或者没有向我们展示它导致的所有错误。