Qt小知識(shí)3.Q_DECLARE_PRIVATE和Q_DECLARE_PUBLIC
1 引言
當(dāng)使用Qt開發(fā)C++應(yīng)用程序時(shí),可以使用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;
#define Q_D(Class) Class##Private * const d = d_func()
#define Q_Q(Class) Class * const q = q_func()
Q_DECLARE_PUBLIC 和 Q_DECLARE_PRIVATE 這兩個(gè)宏一般成對使用,用于實(shí)現(xiàn) PIMPL 設(shè)計(jì)模式,這樣可以達(dá)到隱藏實(shí)現(xiàn)的目的。
2 實(shí)際案例
假設(shè)現(xiàn)在正在開發(fā)一個(gè)音頻播放器應(yīng)用程序,其中有一個(gè)名為AudioPlayer的類負(fù)責(zé)播放音頻文件,這個(gè)類有一些私有成員和方法,需要通過一些公共函數(shù)和方法來訪問。
首先,在AudioPlayer類的頭文件中,使用Q_DECLARE_PRIVATE宏來聲明私有數(shù)據(jù)指針,這個(gè)指針將被用于存儲(chǔ)私有數(shù)據(jù):
#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();
}
在這個(gè)例子中,使用了Q_D宏來定義一個(gè)d指針,該指針指向AudioPlayer類的私有數(shù)據(jù)。
在使用Q_D宏之前,需要在AudioPlayer類實(shí)現(xiàn)文件中包含一個(gè)名為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);
// ...
}
在這個(gè)例子中,使用了Q_Q宏來定義一個(gè)q指針,該指針指向AudioPlayer類。
3 總結(jié)
通過使用Q_DECLARE_PRIVATE、Q_DECLARE_PUBLIC、Q_D和Q_Q宏,可以在Qt應(yīng)用程序中實(shí)現(xiàn)類的封裝和隱藏,同時(shí)提供公共接口來訪問私有成員和方法。這樣可以有效地封裝類的內(nèi)部實(shí)現(xiàn)細(xì)節(jié),提高代碼的可讀性和可維護(hù)性。
每一步踏出,都是一次探索,一次成長。

浙公網(wǎng)安備 33010602011771號(hào)