首页 > 解决方案 > 如何避免多平台qt代码中的特定#ifdef?

问题描述

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

我目前的方法是#ifdef Q_OS_WIN在 header 和 cpp 中使用来执行特定于平台的代码。据我所知,这#ifdef被认为是有害的,应该避免,我想以一种方式重构它,我只有一个头文件inputlistener.h,让构建系统在特定的windows/inputlistener.cppor之间进行选择linux/inputlistener.cpp,也许还有一个inputlistener_global.cpp包含代码的附加文件,即不特定于平台。

但是,我找不到解决方案,如何让#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);
    }
}

标签: c++qtcross-platformmultiplatform

解决方案


您可以为和创建单独EventListener.cpp的文件并将这些文件放入 ( , ) 等子目录中。您可以在 makefile 或 projectfile 中添加一个基于当前平台的实现文件。编译器只会为当前平台编译一个文件。windowsunixwinlinux

使用这种方法,您可以完全避免ifdefing。

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


推荐阅读