c++ - 如何避免多平台qt代码中的specific#ifdef?

标签 c++ qt cross-platform multiplatform

我有一个 QT 输入监听器类,它在运行的 QCoreApplication 中向 stdin 输入发出信号。我想在 Windows 和 Linux 上都使用它。

我当前的方法是在 header 和 cpp 中使用 #ifdef Q_OS_WIN 来执行特定于平台的代码。据我所知,#ifdef 被认为是有害的,应该避免,我想以一种方式重构它,其中我有一个头文件 inputlistener.h 并让构建系统在特定的 windows/inputlistener.cpplinux/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文件windowsunix并将这些文件放入子目录中,例如( winlinux )。您可以在 makefile 或项目文件中添加一个基于当前平台的实现文件。编译器只会为当前平台编译一个文件。

通过这种方法,您可以避免ifdef完全理解。

如果定义不同,您可以使用 pImpl分隔类的实现细节的习惯用法: https://cpppatterns.com/patterns/pimpl.html

关于c++ - 如何避免多平台qt代码中的specific#ifdef?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53433029/

相关文章:

c++ - 为什么在循环之前将 const 标量值分配给 const 会有所帮助?

c++ - 现在对临时工程的非 const 引用?

c++ - QT绘图不删除widget

ios - Xcode5:无法注册“/System/Library/CoreServices/CoreTypes.bundle/Contents/Library/MobileDevices.bundle

docker - 使用 linux 和 win 提取非 root 命名卷权限的工作方法

c++ - 跨平台 C++ 目录管理

c++ - 如何正确使用 Rcpp::pt( )

c++ - 理解右值引用

c++ - 在 QImage 上绘制 QPainterPath 的指定部分 [缩放和平移]

c# - 使用 Qt 获取系统空闲时间