(1)元对象层次的内容概览:
++挨着检查其源码。附录对这些类的整理:
(2) 初步阅读 QMetaObject 的源码,了解其功能:
struct Q_CORE_EXPORT QMetaObject
{
class Connection;
const char * className() const;
const QMetaObject * superClass() const; //返回继承父类
//而 QObject :: parent() 则返回容器父类,用于内存管理
bool inherits(const QMetaObject *metaObject) const noexcept;
//判断本类是否继承于形参类。
//而 QObject::inherits(const char *)用于判断本对象是否是形参类及其子类的实现
QObject * cast(QObject *obj) const //用于类型转换,类似于 C++的 dynamic_cast
{ return const_cast<QObject *>(cast(const_cast<const QObject *>(obj))); }
const QObject *cast(const QObject *obj) const; //常量版本
//功能一样的更好版本是全局模板函数 T * qobject_cast<T *>(A * ptrA)
QMetaType metaType() const; //获取类型的元类型信息
//bool QObject::setProperty (const char * name, const QVariant & value);作为对比
//QVariant QObject::property(const char * name) const; //根据属性名获取属性值,形参是字符串
int propertyOffset () const;//返回此类的属性偏移量;即此类的第一个属性的索引位置。
//偏移量是该类的所有基类中所有属性的总和(由于Q0bject具有name()属性,因此总是正数)
int propertyCount () const;//返回该类中属性的数量,包括每个基类提供的属性的数量。
int indexOfProperty(const char * name) const;//返回具有此名的属性的索引,找不到返-1
//indexOfProperty 的索引基址是 0,搜索范围包括当前类及其所有基类的属性。
QMetaProperty property(int index) const;//返回具有此索引的属性 QMetaProperty对象
int classInfoOffset() const;//返回此类的第一个类信息项的偏移量,即索引位置。
//如果类中没有具有类信息的基类,则偏移量为 0;否则,偏移量为类中所有基类中类信息项的总和。
int classInfoCount () const;//返回的是当前类及其所有基类的类信息总数。
int indexOfClassInfo(const char *name) const;//找不到则返-1
//根据类信息名称返回其在元对象中的类信息索引
//indexOfClassInfo 的索引基址是 0,搜索范围包括当前类及其所有基类的类信息。
QMetaClassInfo classInfo(int index) const; //根据索引返回类信息
//因为c++找工作失败。耐着性子继续学习QT与数据库。我也有些累,焦虑。但没有办法。不学会足够多的本领,如何找工作呢。
//抱歉我有情绪。我是人,不是AI机器。技术会永远传承。但人却有情绪与生命的起止。人不会稳定,只在波浪摆动中前行。谢谢
int indexOfSignal(const char *signal) const;
int indexOfSlot(const char *slot) const;
QMetaProperty userProperty() const; //不懂,暂且保留
// internal index-based connect 内部的基于索引的信号连接,形参有很大区别
static Connection connect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index,
int type = 0, int *types = nullptr);
// internal index-based disconnect j
static bool disconnect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index);
static bool disconnectOne(const QObject *sender, int signal_index,
const QObject *receiver, int method_index);
// internal slot-name based connect
static void connectSlotsByName(QObject *o);
// 使用形式,在窗体的构造函数里这样用 QMetaObject::connectSlotsByName(Widget);
// internal index-based signal activation 内部用的函数
static void activate(QObject *sender, int signal_index, void **argv);
static void activate(QObject *sender, const QMetaObject *,
int local_signal_index, void **argv);
static void activate(QObject *sender, int signal_offset,
int local_signal_index, void **argv);
//似乎是为了处理函数调用的问题。
//毕竟类的静态函数、动态函数,全局函数、对象函数的调用方式是不一样的
//本函数有好几个重载形式,全部删除
static bool invokeMethod(QObject *obj, const char *member,
Qt::ConnectionType,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument());
static inline bool invokeMethod(QObject *obj, const char *member,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument())
{
return invokeMethod(obj, member, Qt::AutoConnection, ret,
val0, val1, val2, val3,
val4, val5, val6, val7, val8, val9);
}
static inline bool invokeMethod(QObject *obj, const char *member,
Qt::ConnectionType type,
QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument())
{
return invokeMethod(obj, member, type, QGenericReturnArgument(),
val0, val1, val2,
val3, val4, val5, val6, val7, val8, val9);
}
static inline bool invokeMethod(QObject *obj, const char *member,
QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument())
{
return invokeMethod(obj, member, Qt::AutoConnection,
QGenericReturnArgument(), val0,
val1, val2, val3, val4, val5, val6, val7, val8, val9);
}
// 本函数似乎是要创建一个对象,QObect 类型或其子类
QObject * newInstance(QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument()) const;
enum Call { //定义了这么一个枚举类,似乎是定义函数的功能与类型
InvokeMetaMethod,
ReadProperty,
WriteProperty,
ResetProperty,
CreateInstance,
IndexOfMethod,
RegisterPropertyMetaType,
RegisterMethodArgumentMetaType,
BindableProperty
};
int static_metacall(Call, int, void **) const;
static int metacall(QObject *, Call, int, void **);
template <const QMetaObject & MO> //模板成员函数
static constexpr const QMetaObject * staticMetaObject() { return & MO; }
struct SuperData {
const QMetaObject * direct; //本类中类的数据成员
SuperData() = default; //无参以及有参构造函数
constexpr SuperData(std::nullptr_t) : direct(nullptr) {}
constexpr SuperData(const QMetaObject *mo) : direct(mo) {}
constexpr const QMetaObject *operator->() const
{ return operator const QMetaObject *(); } //运算符函数 ->
#ifdef QT_NO_DATA_RELOCATION
using Getter = const QMetaObject *(*)();
Getter indirect = nullptr;
constexpr SuperData(Getter g) : direct(nullptr), indirect(g) {}
constexpr operator const QMetaObject *() const
{ return indirect ? indirect() : direct; }
template <const QMetaObject &MO> static constexpr SuperData link()
{ return SuperData(QMetaObject::staticMetaObject<MO>); }
#else
constexpr operator const QMetaObject *() const
{ return direct; }
template <const QMetaObject &MO> static constexpr SuperData link()
{ return SuperData(QMetaObject::staticMetaObject<MO>()); }
#endif
};
struct Data { // private data
SuperData superdata;
const uint *stringdata;
const uint *data;
typedef void (*StaticMetacallFunction)
(QObject *, QMetaObject::Call, int, void **);
StaticMetacallFunction static_metacall;
const SuperData *relatedMetaObjects;
const QtPrivate::QMetaTypeInterface * const * metaTypes;
void *extradata; //reserved for future use
} d; //本类的数据成员
private: //此处声明了一个静态私有函数,以及一个友元类
static bool invokeMethodImpl(QObject *object,
QtPrivate::QSlotObjectBase *slot,
Qt::ConnectionType type, void *ret);
friend class QTimer; //终于浏览完了....,夜里4
};
(3)
谢谢