Qt小知识3.Q_DECLARE_PRIVATE和Q_DECLARE_PUBLIC

发布时间 2024-01-02 17:48:13作者: Qt小罗

1 引言

当使用Qt开发C++应用程序时,可以使用Q_DECLARE_PUBLIC、Q_DECLARE_PRIVATE、Q_D和Q_Q宏来帮助隐藏和公开类的私有成员和方法。

define Q_DECLARE_PRIVATE(Class) \

inline Class##Private* d_func() { return reinterpret_cast<Class##Private >(qGetPtrHelper(d_ptr)); }
inline const Class##Private
d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); }
friend class Class##Private;

define Q_DECLARE_PUBLIC(Class) \

inline Class* q_func() { return static_cast<Class >(q_ptr); }
inline const Class
q_func() const { return static_cast<const Class *>(q_ptr); }
friend class Class;

2 实际案例

假设现在正在开发一个音频播放器应用程序,其中有一个名为AudioPlayer的类负责播放音频文件,这个类有一些私有成员和方法,需要通过一些公共函数和方法来访问。

首先,在AudioPlayer类的头文件中,使用Q_DECLARE_PRIVATE宏来声明私有数据指针,这个指针将被用于存储私有数据:

#ifndef AUDIOPLAYER_H
#define AUDIOPLAYER_H

#include <QObject>

class AudioPlayerPrivate;

class AudioPlayer : public QObject
{
    Q_OBJECT
    Q_DECLARE_PRIVATE(AudioPlayer)

public:
    explicit AudioPlayer(QObject *parent = nullptr);
    ~AudioPlayer();

    void play(const QString& audioFile);
    void stop();

private:
    QScopedPointer<AudioPlayerPrivate> d_ptr;
};

#endif // AUDIOPLAYER_H
#include "audioplayer.h"
#include "audioplayer_p.h"

AudioPlayer::AudioPlayer(QObject *parent)
    : QObject(parent),
      d_ptr(new AudioPlayerPrivate(this))
{
}

AudioPlayer::~AudioPlayer()
{
}

void AudioPlayer::play(const QString &audioFile)
{
    Q_D(AudioPlayer);
    // 使用d指针可以访问私有成员和方法
    d->playInternal(audioFile);
}

void AudioPlayer::stop()
{
    Q_D(AudioPlayer);
    // 使用d指针可以访问私有成员和方法
    d->stopInternal();
}

在这个例子中,使用了Q_D宏来定义一个d指针,该指针指向AudioPlayer类的私有数据。

在使用Q_D宏之前,需要在AudioPlayer类实现文件中包含一个名为audioplayer_p.h的文件,其中声明了AudioPlayerPrivate类,使用Q_DECLARE_PUBLIC宏来声明公共类的指针:

#ifndef AUDIOPLAYER_P_H
#define AUDIOPLAYER_P_H

class AudioPlayer;
class AudioPlayerPrivate
{
    Q_DECLARE_PUBLIC(AudioPlayer)

public:
    AudioPlayerPrivate(AudioPlayer *audioPlayer);

    void playInternal(const QString &audioFile);
    void stopInternal();

private:
    AudioPlayer *q_ptr;
};

#endif // AUDIOPLAYER_P_H

然后,在audioplayer_p.cpp文件中,可以使用Q_Q宏来声明公共类的指针:

#include "audioplayer_p.h"
#include "audioplayer.h"

AudioPlayerPrivate::AudioPlayerPrivate(AudioPlayer *audioPlayer)
    : q_ptr(audioPlayer)
{
}

void AudioPlayerPrivate::playInternal(const QString &audioFile)
{
    // 使用q指针可以访问公共函数和方法
    Q_Q(AudioPlayer);
    // ...
}

void AudioPlayerPrivate::stopInternal()
{
    // 使用q指针可以访问公共函数和方法
    Q_Q(AudioPlayer);
    // ...
}

在这个例子中,使用了Q_Q宏来定义一个q指针,该指针指向AudioPlayer类。

总结

通过使用Q_DECLARE_PRIVATE、Q_DECLARE_PUBLIC、Q_D和Q_Q宏,我们可以在Qt应用程序中实现类的封装和隐藏,同时提供公共接口来访问私有成员和方法。这样可以有效地封装类的内部实现细节,提高代码的可读性和可维护性。