指向与对象类型不兼容的成员类型的指针 → 原因是什么?
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 行)应该会产生错误。因此,您似乎没有向我们展示与创建错误消息的代码完全相同的代码,或者没有向我们展示它导致的所有错误。
最近我 运行 编译器 (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 行)应该会产生错误。因此,您似乎没有向我们展示与创建错误消息的代码完全相同的代码,或者没有向我们展示它导致的所有错误。