1 反射机制
C#中支持反射机制而C++中不支持,基于QT的元对象系统,之前使用QT的反射机制创建属性表,现学习使用QT通过类名动态创建对象。
反射机制的优点:
- 1、反射提高了程序的灵活性和扩展性。
- 2、降低耦合性,提高自适应能力。
- 3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
2 结果现象
输入MyClass类名,可以动态创建对象,访问类中的属性方法。
3 程序代码
mainwindow.h
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QMainWindow> 5 #include <QByteArray> 6 #include <QMetaObject> 7 #include <QHash> 8 #include <QLineEdit> 9 #include <QMetaProperty> 10 #include <QPushButton> 11 #include <QDebug> 12 #pragma execution_character_set("utf-8") 13 14 QT_BEGIN_NAMESPACE 15 namespace Ui { class MainWindow; } 16 QT_END_NAMESPACE 17 class MyClass; 18 19 class MyClass : public QWidget 20 { 21 Q_OBJECT 22 public: 23 24 MyClass(QWidget *parent = nullptr); 25 Q_PROPERTY(uint uCrc READ uCrc WRITE setuCrc) 26 Q_PROPERTY(uint StructLen READ StructLen WRITE setStructLen) 27 ~MyClass(); 28 int num; 29 void pCout(); 30 31 uint uCrc() const 32 { 33 qDebug()<<"uCrc"<<m_uCrc; 34 return m_uCrc; 35 } 36 uint StructLen() const 37 { 38 return m_StructLen; 39 } 40 41 public slots: 42 void setuCrc(uint uCrc) 43 { 44 qDebug()<<"setuCrc"<<uCrc<<"success!!!!!!!!!!!!!!!"; 45 m_uCrc = uCrc; 46 } 47 void setStructLen(uint StructLen) 48 { 49 m_StructLen = StructLen; 50 } 51 52 private: 53 uint m_uCrc; 54 uint m_StructLen; 55 }; 56 57 class MainWindow : public QMainWindow 58 { 59 Q_OBJECT 60 61 public: 62 MainWindow(QWidget *parent = nullptr); 63 ~MainWindow(); 64 65 QStringList m_Register; 66 67 void create(QString name); 68 69 private slots: 70 void on_lineEdit_editingFinished(); 71 72 private: 73 Ui::MainWindow *ui; 74 }; 75 76 #ifndef REFLECT_H 77 #define REFLECT_H 78 template<typename L> 79 class Reflect 80 { 81 public: 82 83 template<typename T> 84 static void registerClass(QString name) 85 { 86 constructors().insert( name.toLatin1(), &constructorHelper<T> ); 87 } 88 89 static QObject* newInstance( const QByteArray& className, L* parent = nullptr ) 90 { 91 Constructor constructor = constructors().value( className ); 92 if ( constructor == nullptr ) 93 return nullptr; 94 return (*constructor)( parent ); 95 } 96 97 private: 98 typedef QObject* (*Constructor)( L* parent ); 99 100 template<typename T> 101 static QObject* constructorHelper( L* parent ) 102 { 103 return new T( parent ); 104 } 105 106 static QHash<QByteArray, Constructor>& constructors() 107 { 108 static QHash<QByteArray, Constructor> instance; 109 return instance; 110 } 111 }; 112 113 #endif // REFLECT_H 114 #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); Reflect<QWidget>::registerClass<QLineEdit>("QLineEdit"); Reflect<QWidget>::registerClass<QPushButton>("QPushButton"); Reflect<QWidget>::registerClass<MyClass>("MyClass"); m_Register.append("QLineEdit"); m_Register.append("QPushButton"); m_Register.append("MyClass"); } MainWindow::~MainWindow() { delete ui; } void MainWindow::create(QString name) { qDebug()<<"start"; QObject *object = Reflect<QWidget>::newInstance(name.toUtf8()); const QMetaObject *p = object->metaObject(); //打印属性与方法名 for(int i = 0;i < p->methodCount();i++) { qDebug()<<p->method(i).name()<<"~~~~~~method~~~~~~"; } for(int i = 0;i < p->propertyCount();i++) { qDebug()<<p->property(i).name()<<"----property---"; } /** * @brief 动态创建名称为 name 的类 * 该程序测试的类名 name = MyClass * 之后进行测试打印 MyClass类 中的uCrc * 成功打印setuCrc 12 success!!!!!!!!!!!!!!! * */ qDebug()<<"==============================="; QMetaProperty pe = p->property(p->indexOfProperty("uCrc")); pe.write(object,12); qDebug()<<"end"; } MyClass::MyClass(QWidget *parent) { parent = nullptr; } MyClass::~MyClass() { delete this; } void MyClass::pCout() { qDebug()<<"pCout"; } void MainWindow::on_lineEdit_editingFinished() { QString str = ui->lineEdit->text(); if(!m_Register.contains(str)) return ; this->create(str); }
main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
标签:return,Qt,parent,创建对象,MyClass,include,MainWindow,类名,name From: https://www.cnblogs.com/qter/p/16723279.html