为了测试Qt中的TCP通信,我用到了Qt里的 QTcpSocket,写了段非常简单的测试代码。
其中遇到了点麻烦。
在对 QTcpSocket 写测试代码时,想 connect QTcpSocket 的 error 信号时会出错。
如下:
原因是 QTcpSocket 除了有一个信号叫 error(),还有一个 error() 的成员函数也叫这个。
它们是重载函数。
问题的关键是:QObject::connect() 函数无法根据后面 function 的参数类型来知晓 第二个参数中的 error 到底是指的这两个函数中的哪一个。
于是,我写了一个测试工程。
my_class.h
#ifndef MY_CLASS_H
#define MY_CLASS_H
#include <QDebug>
class Sender : public QObject {
Q_OBJECT
public:
signals:
void overloadEvent(int a); //! 重载的信号
void overloadEvent(QString a); //! 重载的信号
void normalEvent(int a);
};
class Receiver : public QObject {
Q_OBJECT
public slots:
void onEvent(int a) {
qDebug() << "event:" << a;
}
void onEvent(QString a) {
qDebug() << "event:" << a;
}
};
#endif // MY_CLASS_H
定义了两个类:一个是 Sender类,它有三个信号。其中 overloadEvent 信号是两个被重载的函数。而 normalEvent 则没有被重载。
另一个是 Receiver 类中只定义了两个 slots,分别对应 Sender 的两种信号。
main.cpp
#include "my_class.h"
int main()
{
Sender s;
Receiver r;
QObject::connect(&s, SIGNAL(overloadEvent(int)), &r, SLOT(onEvent(int))); //!(1)
QObject::connect(&s, SIGNAL(overloadEvent(QString)), &r, SLOT(onEvent(QString))); //!(2)
QObject::connect(&s, &Sender::normalEvent, [](int a) { //!(3)
qDebug() << "lambda1:" << a;
});
QObject::connect(&s, &Sender::overloadEvent, [](int a) { //!(4)
qDebug() << "lambda2:" << a;
});
s.overloadEvent(12);
s.overloadEvent("Hello world");
return 0;
}
上述代码中,(1)(2)(3)处均正常。
唯有(4)红色部分代码是编译不过的,提示:
也就是,这么写是没有参数信息的。它不知道具体使用的是两个重载函数的哪一个。
为什么(1)(2)正常呢?因为它们是使用的这个 QObject::connect() 函数:
因为 (1)(2)使用的是 第1个函数。而(4)是使用的 第2个函数。
为了指定具体是哪一个函数,可以曲线救国一下:
在 L21,先定义一个函数指针 func,将 &Sender::overloadEvent 赋值给它。这个过程 func 得到的就是 overloadEvent(int),而不是 overloadEvent(QString)。
然后在 L22,使用 func 作为 QObject::connect() 的第二个参数。
我们可以进一步简化一下,直接使用强制转换:
这样一步到位。
测试结果符合我们的预期。
修改后的完整 main.cpp 代码:
#include "my_class.h"
int main()
{
Sender s;
Receiver r;
QObject::connect(&s, SIGNAL(overloadEvent(int)), &r, SLOT(onEvent(int)));
QObject::connect(&s, SIGNAL(overloadEvent(QString)), &r, SLOT(onEvent(QString)));
QObject::connect(&s, &Sender::normalEvent, [](int a) {
qDebug() << "lambda1:" << a;
});
QObject::connect(&s, (void(Sender::*)(int))(&Sender::overloadEvent), [](int a) {
qDebug() << "lambda4:" << a;
});
QObject::connect(&s, (void(Sender::*)(QString))(&Sender::overloadEvent), [](QString a) {
qDebug() << "lambda4:" << a;
});
s.overloadEvent(12);
s.overloadEvent("Hello world");
return 0;
}
运行结果:
所以最前面 QTcpSocket 的例子,应该写成: