这一次主要看的是qundostack*文件,之前关于命令模式有了一个初步的了解,希望在看完后可以有进一步的认识,或者关于Qt在这里有没有使用该模式有一个自己的定义。
为了以后看起来更方便一些,这篇笔记以整理Qt里的宏定义为主,宏本身在代码里使用还是非常广泛的。
因为是一边看一边做笔记,难免会因为管中窥豹一知半解而漏洞百出,因此有不对或者疑惑的地方还请尽量指出。无论如何,我对自己的要求是坚持学习Qt源码的这一计划,希望点点滴滴的理解可以最后星火燎原,使我这个跨入IT的理科生能够理解编程。
1. Q_DISABLE_COPY(Class)
(禁止复制构造函数和赋值)
在QundoCommand类定义里出现过(Q_DISABLE_COPY(QUndoCommand)),直接看个例子,关于宏定义本身照抄的Qt。
#define Q_DISABLE_COPY(Class) \
Class(const Class &); \
Class &operator=(const Class &);
class A {
public:
A() {}
private:
Q_DISABLE_COPY(A)
};
用cpp预编译后的文件:
# 1 "main.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.cpp"
class A {
public:
A() {}
private:
A(const A &); A &operator=(const A &);
};
注意要放在private段里。
可以看到效果~好的,第一个宏ok了,是不是非常简单?
2. Q_DECLARE_PRIVATE(Class)
该宏定义了函数d_func(分别对于const和非const对象),声明一个友元类。
还是看个例子:
#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;
class A {
public:
Q_DECLARE_PRIVATE(A)
};
看下预编译后的文件:
# 1 "main.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.cpp"
class A {
public:
inline APrivate* d_func() { return reinterpret_cast<APrivate *>(qGetPtrHelper(d_ptr)); } inline const APrivate* d_func() const { return reinterpret_cast<const APrivate *>(qGetPtrHelper(d_ptr)); } friend class APrivate;
};
先不用管qGetPtrHelper以及d_ptr。主要看下这个宏的作用就行。
注意是Aprivate而不是ClassPrivate,是##的作用。同时Qt源码里很多类都相应的定义了其形如XXXprivate的类。例如qundostack_p.h里定义了QundoCommandPrivate,QundoStackPrivate(public QObjectPrivate)的类。
补充1:关于qGetPtrHelper定义如下
template <typename T> static inline T *qGetPtrHelper(T *ptr) { return ptr; }
template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelper(const Wrapper &p) { return p.data(); }
注意第二个定义里typename要写在这里的原因之前介绍过。
补充2:关于d_ptr。
QundoStack实际上实际上继承自Qobject类。
在Qobject类里这么定义的:
QScopedPointer<QObjectData> d_ptr;
3. Q_D(class),Q_Q(class)分别在类x以及其形如xPrivate的类里获取对方的指针d或q。
可以看到这里调用的即是d_func(),q_func()定义是类似的。因此不要再尝试自己定义d或者q指针!
#define Q_D(Class) Class##Private * const d = d_func()
#define Q_Q(Class) Class * const q = q_func()
此外还有很多,上面列的几个算是基本的介绍,在corelib/global/qglobal.h里都有定义,如果要了解的话还是得自己一个个去查,挨着列出来的话没有必要也没什么作用。常见的在QtAssistant里也可以查到,比如Q_PROPERY等。比如Q_FOREACH的定义等,我觉得看下还是很多有好处的。