惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Latest
Security Latest
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
N
Netflix TechBlog - Medium
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
C
Cyber Attacks, Cyber Crime and Cyber Security
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
J
Java Code Geeks
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MyScale Blog
MyScale Blog
T
Tor Project blog
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
P
Privacy & Cybersecurity Law Blog
MongoDB | Blog
MongoDB | Blog
Simon Willison's Weblog
Simon Willison's Weblog
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
小众软件
小众软件
G
GRAHAM CLULEY
P
Privacy International News Feed
AWS News Blog
AWS News Blog
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
人人都是产品经理
人人都是产品经理
S
Schneier on Security
Scott Helme
Scott Helme
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
T
The Exploit Database - CXSecurity.com
Recent Announcements
Recent Announcements
E
Exploit-DB.com RSS Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
U
Unit 42
The Register - Security
The Register - Security
S
Securelist
Martin Fowler
Martin Fowler
Project Zero
Project Zero
大猫的无限游戏
大猫的无限游戏
Cisco Talos Blog
Cisco Talos Blog

博客园 - 鬼谷子com

2026年国内主流AI Coding Plan套餐全对比|开发者避坑指南 图解 | 你管这破玩意儿叫TCP?(转载) C++ static_cast、dynamic_cast、const_cast和reinterpret_cast(四种类型转换运算符) Qt内部的d指针和q指针手把手教你实现 C++中虚函数、虚继承内存模型 c++11新特性实战(二):智能指针 windows下使用mingw和msvc静态编译Qt5.15.xx c++结构体内存对齐 c++11新特性实战 (一):多线程操作 抽象工厂模式(c++实现) 迭代器模式(c++实现) 中介者模式(c++实现) 享元模式(c++实现) 代理模式(c++实现) 状态模式(c++实现) - 鬼谷子com 建造者模式(c++实现) 职责链模式(c++实现) 命令模式(c++实现) 模板方法模式(c++实现)
Qt moc元对象编译器的原理和场景(反射)
鬼谷子com · 2020-12-15 · via 博客园 - 鬼谷子com

Qt Meta-Object Compiler (moc)

元对象编译器,能够实现运行时类型识别。可以用在需要用到反射机制的情况下,qml使用c++的类和方法就是使用了这个特性,通过Q_PROPERTY在类内注册属性;

使用Qt的元对象系统的方法:

  1. 类要继承自QObject

  2. 在类申明开始写上Q_OBJECT宏,Q_OBJECT宏的展开为:

     static const QMetaObject staticMetaObject; \
     virtual const QMetaObject *metaObject() const; \
     virtual void *qt_metacast(const char *); \
     virtual int qt_metacall(QMetaObject::Call, int, void **); \
     Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
    

moc识别到这个宏之后会编译出moc_youclass.cpp文件,里面有这几个方法和函数的定义和使用;

myclass.h

#ifndef MYCLASS_H
#define MYCLASS_H

#include <QObject>

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
    Q_PROPERTY(int size READ size WRITE setSize NOTIFY sizeChanged)
public:
    explicit MyClass(QObject *parent = nullptr);

    Q_INVOKABLE  void PrintSelf();
    QString name() const
    {
        return m_name;
    }

    size_t size() const
    {
        return m_size;
    }

signals:

    void nameChanged(QString name);

    void sizeChanged(size_t size);

public slots:

void setName(QString name)
{
    if (m_name == name)
        return;

    m_name = name;
    emit nameChanged(m_name);
}

void setSize(size_t size)
{
    if (m_size == size)
        return;

    m_size = size;
    emit sizeChanged(m_size);
}

private:
    QString m_name;
    int m_size;
};

#endif // MYCLASS_H

main.cpp

#include <QCoreApplication>
#include <iostream>
#include <QVariant>
#include <QDebug>
#include <QMetaMethod>
#include "myclass.h"
using namespace std;

void test()
{
    cout << "-------test property-----------" << "\n";
    MyClass newObj;
    newObj.setProperty("type", "fuck");
    newObj.setProperty("Member1", 66);
    cout << newObj.property( "Member1" ).toString().toStdString() << "\n";
    const QMetaObject* mobj = newObj.metaObject();
    qDebug() << "obj name = " << mobj->className();

    int propertyCount = mobj->propertyCount();
    for(int n = 0; n < propertyCount; ++n)
    {
        qDebug() << "property index : " << n;
        QMetaProperty property = mobj->property(n);
        qDebug() << "property : " << property.name();
        qDebug() << "property value : " << property.read(&newObj);
    }

    int methodCount = mobj->methodCount();
    for(int n = 0; n < methodCount; ++n)
    {
        qDebug() << "method index : " << n;
        QMetaMethod method = mobj->method(n);
        qDebug() << "method name : " << method.name();
        method.invoke(&newObj);
    }

 QMetaObject::invokeMethod( &newObj, "PrintSelf", Qt::DirectConnection);

    MyClass* myClass = dynamic_cast<MyClass*>(mobj->newInstance());
    cout << "--------end----------" << "\n";
}

int main(int argc, char *argv[])
{
    test();
    QCoreApplication a(argc, argv);

    return a.exec();
}