1. 程式人生 > >Qt通過類名稱建立類的例項的兩種方法

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巨集