出于设计原因,我需要想出一种方法来调用QObject::connect()
,其中函数指针作为函数调用的返回值传递。即,我不必使用原始语法connect(sender, &Sender::valueChanged, receiver, &Receiver::updateValue);
,而必须执行以下操作:
//in main.cpp
SENDER *sender = new SENDER;
RECEIVER *receiver = new RECEIVER;
connect(sender, sender->get_func(), receiver, receiver->get_func() );
其中SENDER和RECEIVER的定义如下:
#include <QObject>
class SENDER : public QObject {
Q_OBJECT
public:
void(* get_func() ) (double, double);
signals:
void send_data(double x, double y);
};
void (* SENDER::get_func() )(double, double)
{
return send_data;
}
class RECEIVER : public QObject {
Q_OBJECT
public:
void receive_data(double x, double y);
void(* get_func() ) (double, double);
};
void (* RECEIVER::get_func() )(double, double)
{
return receive_data;
}
int main()
{
SENDER *sender = new SENDER;
RECEIVER *receiver = new RECEIVER;
QObject::connect(sender, sender->get_func(), receiver, receiver->get_func() );
}
尝试编译会给我以下错误:
/home/abc/work/mainwindow.cpp:41: error: no matching function for call to ‘MainWindow::connect(SENDER*&, void (*)(double, double), RECEIVER*&, void (*)(double, double))’
connect(sender, sender->get_func(), receiver, receiver->get_func() );
我在这里做什么错了?
答案 0 :(得分:2)
您的get_func
不会返回指针指向成员的函数,这是connect期望的。他们正在返回指向功能的指针。
您应该改为将其声明为
//sender.h
#include <QWidget>
class SENDER : public QWidget{
Q_OBJECT
public:
void (SENDER::*get_func)(double, double)();
signals:
void send_data(double x, double y);
};
//sig_sender.cpp
#include "sender.h"
void (SENDER::*)(double, double) SENDER::get_func()
{
return &SENDER::send_data;
}
//sig_receiver.h
#include <QWidget>
class RECEIVER : public QWidget{
Q_OBJECT
public:
void receive_data(double x, double y);
void (RECEIVER::*get_func)(double, double)();
};
//sig_receiver.cpp
#include "receiver.h"
void (RECEIVER::*)(double, double) RECEIVER::get_func()
{
return &RECEIVER::receive_data;
}
答案 1 :(得分:2)
您的函数未返回成员函数指针。 SENDER
的写法如下:
class SENDER : public QObject {
Q_OBJECT
public:
void (SENDER::*get_func())(double, double);
signals:
void send_data(double x, double y);
};
void (SENDER::*SENDER::get_func())(double, double)
{
return &SENDER::send_data;
}
get_func()
需要声明为返回指向成员函数的指针,该指针采用(double, double)
并返回void
。实现需要限定要返回的成员的名称,并使用地址操作符&
。
必须对RECEIVER
进行类似的更改:
class RECEIVER : public QObject {
Q_OBJECT
public:
void receive_data(double x, double y);
void (RECEIVER::*get_func())(double, double);
};
void (RECEIVER::*RECEIVER::get_func())(double, double)
{
return &RECEIVER::receive_data;
}
答案 2 :(得分:1)
一种可能的解决方案是使用auto
推导类型(C ++ 14)并返回&Class::method
:
#include <QCoreApplication>
#include <QTimer>
#include <QDebug>
class SENDER : public QObject{
Q_OBJECT
public:
auto get_func(){
return &SENDER::send_data;
}
signals:
void send_data(double x, double y);
};
class RECEIVER : public QObject
{
Q_OBJECT
public:
void receive_data(double x, double y){
qDebug()<< __PRETTY_FUNCTION__ << x <<y;
QCoreApplication::quit();
}
auto get_func(){
return &RECEIVER::receive_data;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
SENDER *sender = new SENDER;
RECEIVER *receiver = new RECEIVER;
QObject::connect(sender, sender->get_func(), receiver, receiver->get_func());
QTimer::singleShot(1000, sender, [sender](){
emit sender->send_data(1.0, 2.0);
});
return a.exec();
}
#include "main.moc"
或者:
class SENDER : public QObject{
Q_OBJECT
public:
void (SENDER::*get_func())(double, double){
return &SENDER::send_data;
}
signals:
void send_data(double x, double y);
};
class RECEIVER : public QObject
{
Q_OBJECT
public:
void receive_data(double x, double y){
qDebug()<< __PRETTY_FUNCTION__ << x <<y;
QCoreApplication::quit();
}
void (RECEIVER::*get_func())(double, double){
return &RECEIVER::receive_data;
}
};
答案 3 :(得分:1)
您可以使用using
或typedef
来定义指向成员函数的指针的类型:
class SENDER : public QWidget{
Q_OBJECT
public:
typedef void (SENDER::*PtrFunc)(double,double); // PtrFunc pointer to member function
PtrFunc get_func () { return &SENDER::send_data; }
signals:
void send_data(double x, double y) {}
};
class RECEIVER : public QWidget{
Q_OBJECT
public:
using PtrFunc = void (RECEIVER::*)(double,double);
void receive_data(double x, double y) {}
PtrFunc get_func() { return &RECEIVER::receive_data; }
};
SENDER* sender;
RECEIVER* receiver;
//..
QObject::connect (sender, sender->get_func(), receiver, receiver->get_func());
使用typedef可以很容易地将其作为结果类型。