我有一个 QT 输入监听器类,它在运行的 QCoreApplication
中向 stdin
输入发出信号。我想在 Windows 和 Linux 上都使用它。
我当前的方法是在 header 和 cpp 中使用 #ifdef Q_OS_WIN
来执行特定于平台的代码。据我所知,#ifdef 被认为是有害的,应该避免,我想以一种方式重构它,其中我有一个头文件 inputlistener.h
并让构建系统在特定的 windows/inputlistener.cpp
或 linux/inputlistener.cpp
之间进行选择,也许还有一个保存代码的附加 inputlistener_global.cpp
,这不是特定于平台的。
但是,我找不到解决方案,如何将 header 中的 #ifdef
去掉。
我怎样才能实现这一目标?
这是我当前的方法:
#inputlistener.h
#ifndef INPUTLISTENER_H
#define INPUTLISTENER_H
#include <QtCore>
class inputlistener : public QObject {
Q_OBJECT
private:
#ifdef Q_OS_WIN
QWinEventNotifier* m_notifier;
#else
QSocketNotifier* m_notifier;
#endif
signals:
void inputeventhappened(int keycode);
private slots:
void readyRead();
public:
inputlistener();
};
#endif // INPUTLISTENER_H
#inputlistener.cpp
#include "inputlistener.h"
#include "curses.h"
#ifdef Q_OS_WIN
#include <windows.h>
#endif
inputlistener::inputlistener()
{
#ifdef Q_OS_WIN
m_notifier = new QWinEventNotifier(GetStdHandle(STD_INPUT_HANDLE));
connect(m_notifier, &QWinEventNotifier::activated
#else
m_notifier = new QSocketNotifier(0, QSocketNotifier::Read, this);
connect(m_notifier, &QSocketNotifier::activated
#endif
,
this, &inputlistener::readyRead);
readyRead(); // data might be already available without notification
}
void inputlistener::readyRead()
{
// It's OK to call this with no data available to be read.
int c;
while ((c = getch()) != ERR) {
emit inputeventhappened(c);
}
}
最佳答案
您可以创建单独的 EventListener.cpp
文件windows
和unix
并将这些文件放入子目录中,例如( win
, linux
)。您可以在 makefile 或项目文件中添加一个基于当前平台的实现文件。编译器只会为当前平台编译一个文件。
通过这种方法,您可以避免ifdef
完全理解。
如果定义不同,您可以使用 pImpl
分隔类的实现细节的习惯用法: https://cpppatterns.com/patterns/pimpl.html
关于c++ - 如何避免多平台qt代码中的specific#ifdef?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53433029/