Qt通过类名称创建类的实例的两种方法

1 通过qRegisterMetaType和QMetaType

#ifndef ANIMAL_H
#define ANIMAL_H

class Animal
{
public:
    Animal();

    virtual void voice();
};

#endif // ANIMAL_H
#include "animal.h"

Animal::Animal()
{

}

void Animal::voice()
{

}
#ifndef DOG_H
#define DOG_H

#include "animal.h"

class Dog : public Animal
{
public:
    Dog();

    void voice();
};

#endif // DOG_H
#include "dog.h"
#include <QDebug>

Dog::Dog()
{

}

void Dog::voice()
{
    qDebug()<<"wang!";
}
#ifndef CAT_H
#define CAT_H

#include "animal.h"

class Cat : public Animal
{
public:
    Cat();

    void voice();
};

#endif // CAT_H
#include "cat.h"
#include <QDebug>

Cat::Cat()
{

}

void Cat::voice()
{
    qDebug()<<"miao~";
}
#include <QDebug>
#include "dog.h"
#include "cat.h"

int main(int argc, char *argv[])
{
    qDebug()<<"Register class ...";
    qRegisterMetaType<Dog>("Dog");
    qRegisterMetaType<Cat>("Cat");

    qDebug()<<"Create Dog ...";
    int id=QMetaType::type("Dog");
    if(id > 0)
    {
        Animal *animal=static_cast<Animal*>(QMetaType::create(id));
        animal->voice();
    }

    qDebug()<<"Create Cat ...";
    id=QMetaType::type("Cat");
    if(id > 0)
    {
        Animal *animal=static_cast<Animal*>(QMetaType::create(id));
        animal->voice();
    }

    qDebug()<<"Finished!";

    return 0;
}

运行结果:

注意:经测试,当对象是QObject的子类时无法使用这个方法,此时调用qRegisterMetaType编译时会报错

2 通过QMetaObject的newInstance函数

#ifndef ANIMAL_H
#define ANIMAL_H

#include <QObject>

class Animal : public QObject
{
public:
    Animal();

    virtual void voice();
};

#endif // ANIMAL_H
#include "animal.h"

Animal::Animal()
{

}

void Animal::voice()
{

}
#ifndef DOG_H
#define DOG_H

#include "animal.h"

class Dog : public Animal
{
    Q_OBJECT
public:
    Q_INVOKABLE Dog();

    void voice();
};

#endif // DOG_H
#include "dog.h"
#include <QDebug>

Dog::Dog()
{

}

void Dog::voice()
{
    qDebug()<<"wang!";
}
#ifndef CAT_H
#define CAT_H

#include "animal.h"

class Cat : public Animal  //Cat必须是QObject的子类
{
    Q_OBJECT    //必须添加Q_OBJECT
public:
    Q_INVOKABLE Cat();  //默认构造函数前必须使用Q_INVOKABLE

    void voice();
};

#endif // CAT_H
#include "cat.h"
#include <QDebug>

Cat::Cat()
{

}

void Cat::voice()
{
    qDebug()<<"miao~";
}
#include <QDebug>
#include <QMap>
#include "dog.h"
#include "cat.h"

int main(int argc, char *argv[])
{
    qDebug()<<"Register class ...";
    QMap<QString, QMetaObject> metaMap;
    metaMap.insert("Dog", Dog::staticMetaObject);
    metaMap.insert("Cat", Cat::staticMetaObject);

    qDebug()<<"Create Dog ...";
    Animal *animal=static_cast<Animal*>(metaMap.value("Dog").newInstance());
    if(animal)
    {
        animal->voice();
    }

    qDebug()<<"Create Cat ...";
    animal=static_cast<Animal*>(metaMap.value("Cat").newInstance());
    if(animal)
    {
        animal->voice();
    }

    qDebug()<<"Finished!";

    return 0;
}

 运行效果:

注意:经测试,按照这一种方法创建实例时,实例对应的类应该满足如下条件

          (1) 类是QObject的子类

          (2) 类头文件中必须添加Q_OBJECT宏

          (3) 类头文件的默认构造函数的前面必须添加Q_INVOKABLE宏

猜你喜欢

转载自blog.csdn.net/zgrjkflmkyc/article/details/84837541