4

2 つのサブクラスに継承される基本クラスがあります。3 つのクラスはすべて、qDebug() を使用してデバッグ印刷を行い、Q_FUNC_INFO を使用して印刷のソースを識別します。問題は、基本クラスから印刷する場合、Q_FUNC_INFO に基本クラスの名前が含まれているため、インスタンスが 2 つのサブクラスのどちらを表しているかを知ることができないことです。

これまでに思いついた最善の解決策は、基本クラスで Q_FUNC_INFO の代わりに QString 変数を使用し、インスタンス化するときに正しい名前を指定することです。

他のより好ましい解決策はありますか?

4

1 に答える 1

4

他のより好ましい解決策はありますか?

一般的には、いいえ、それで問題ありません。このような場合、可能であれば Q_FUNC_INFO をサブクラスに配置する必要があります。そうでない場合は運が悪いですが... 読み進めてください。

Qt は内部的にも Q_FUNC_INFO ではなく明示的な文字列を使用しています。

QObjects の場合、イントロスペクションにメタ オブジェクト コンパイラを使用して、実際の名前を動的に取得できます。つまり、次のようになります。

const char * QMetaObject::className() const

クラス名を返します。

const QMetaObject * QObject::metaObject() const [仮想]

このオブジェクトのメタオブジェクトへのポインターを返します。

メタオブジェクトには、クラス名、スーパークラス名、プロパティ、シグナル、スロットなど、QObject を継承するクラスに関する情報が含まれています。Q_OBJECT マクロを含むすべての QObject サブクラスには、メタオブジェクトがあります。

メタオブジェクト情報は、シグナル/スロット接続メカニズムとプロパティ システムによって必要とされます。inherits() 関数もメタオブジェクトを利用します。

実際のオブジェクト インスタンスへのポインターがなくても、クラスのメタオブジェクトにアクセスしたい場合は、staticMetaObject を使用できます。

あなたのコメントがそれを示しているように見えるので、コンストラクターを扱うときもこれを調べます:

QMetaMethod QMetaObject::constructor(int index) const

指定されたインデックスを持つコンストラクターのメタデータを返します。

main.cpp

#include <QObject>
#include <QDebug>

class Foo : public QObject
{
    Q_OBJECT
    public:
        virtual void baz() {  qDebug() << "Class name:" << metaObject()->className(); }
};

class Bar : public Foo
{
    Q_OBJECT
};

#include "main.moc"

int main()
{
    Bar bar;
    bar.baz();
    return 0;
}

出力

moc main.cpp -o main.moc && g++ -Wall -I/usr/include/qt -I/usr/include/ -I/usr/include/qt/QtCore -lQt5Core -fPIC main.cpp && ./a.out

Class name: Bar

注: コンストラクターでこのメカニズムを機能させたい場合、単純な答えはできないということです。そこでは何も役に立ちません。これは、C++ での継承の処理方法によるものです。まず、基本クラスが構築され、その段階では、サブクラスはまだ完全に構築されているため (厳密に言えば、基本でさえありません)、基本クラスへの追加の引数で明示的に確認しない限り、それに関する詳細情報を実際に取得することはできません。コンストラクタ。しかし、そうすると、この単純なことだけのために肥大化した API を手に入れることになります。このような場合、基本クラスではなくサブクラスに印刷を入れることをお勧めします。

于 2013-12-19T09:07:35.217 に答える