1

どのクラスがいくつかの異なるタイプからサブクラス化されているかを判断しようとしています。たとえば、E1がAを拡張し、E2がAを拡張し、E3がBを拡張する場合、Aからサブクラス化されたすべてのクラスを検索し、タイプE1およびE2のリストを返します。これらのタイプはQMetaSystemに登録されています。

私の最初の試みは、ユーザーが宣言した型を反復処理してインスタンス化し、superClass名を取得することでした。

int type = QMetaType::User;
while( QMetaType::isRegistered(type) ) {
    QObject *o = (QObject*)QMetaType::construct(type);
    QString parent = o->metaObject()->superClass()->className();
}

私がそれを書いたとき、これは悪い考えのように思えました、そしてそれがうまくいくとは思っていませんでした。当然のことながら、metaObjectを取得しようとするとsegfaultが発生します。

QMetaTypeから必要な情報を取得することは可能ですか、それともこの情報を取得する別の方法がありますか?

アップデート

問題は、すべてのユーザータイプを反復しようとすることにあるようです。タイプを登録する前に、いくつかのQtタイプが私の前に登録されているようです。具体的には、登録されている2つのタイプはQPaintBufferCacheEntry(typeId = 256)とQPaintBufferCacheEntryV2(typeId = 257)です。オブジェクトは問題なく初期化できますが、メタオブジェクトを取得しようとするとクラッシュするため、キャストは違法だと思います。私のコードベースは明示的に登録していないため、これらがどこに登録されているのかよくわかりません。

私はこれを、各ユーザータイプを繰り返して構築するのは安全ではないことを意味すると解釈しました。

4

1 に答える 1

1

あなたの考えは正しいです。これにより、親クラスの名前が得られます。

QObject *o = (QObject*)QMetaType::construct(type);
QString parent = o->metaObject()->superClass()->className();

それが機能するには、クラスが で宣言されQ_DECLARE_METATYPE(Type)、登録されている必要がありますqRegisterMetaType()。これはQMetaType::isRegistered(type)事実です。

ユーザー定義のクラスも QObject から (直接または非直接的に) 継承しその定義にQ_OBJECT マクロを含める必要があります。これはセグメンテーション違反を説明する可能性があります。

superClass()親クラスがない場合は 0 を返すこともできますが、ここではすべてのクラスが少なくとも QObject を継承する必要があります。

またQObject::inherits(const char * className)、オブジェクトが className から間接的であっても継承するクラスであるかどうかを知る必要もあります。

于 2012-11-07T21:36:01.807 に答える