1

シングルトンデザインパターンを使用するJellyfishという名前のクラスがあります:

クラゲ.h

#ifndef JELLYFISH_H
#define JELLYFISH_H

#include <QHash>
#include <QScriptEngine>

class QScriptValue;

class Jellyfish : public QObject
{

    public:

         static Jellyfish * getInstance();
         static Jellyfish * instance;

    private:

        Jellyfish();

};

#ifndef

クラゲ.cpp

Jellyfish * Jellyfish::instance = NULL;

Jellyfish * Jellyfish::getInstance()
{

    if ( !Jellyfish::instance )
    {
        Jellyfish::instance = new Jellyfish();
    }

    return Jellyfish::instance;

}

main.cpp でテストを行っても、エラーは発生しません。

main.cpp

#include <QApplication>

#include "jellyfish.h"

class Jellyfish;

int main( int argc, char *argv[] )
{

    QApplication app( argc, argv );

    Jellyfish *toto = Jellyfish::getInstance();
    Jellyfish *toto2 = Jellyfish::getInstance();
    Jellyfish *toto3 = Jellyfish::getInstance();

    return app.exec();

}

Jellyfishしかし、外部QScriptファイルでいくつかの静的メソッドを使用したい:

クラゲ.h

private:

    static QScriptValue set( QScriptContext *context, QScriptEngine *engine );
    QScriptEngine *script_engine;

クラゲ.cpp

Jellyfish::Jellyfish()
{

    script_engine = new QScriptEngine;

    /* ... */

    initScriptEngine();

}

void Jellyfish::initScriptEngine()
{

    QScriptValue object = script_engine->newQObject( this );

    object.setProperty( "set", script_engine->newFunction( set ) );

    script_engine->globalObject().setProperty( "jellyfish", object );

}

QScriptValue Jellyfish::set( QScriptContext *context, QScriptEngine *engine )
{

    // I have to load instance because I am in a static method.
    // But this is where the application loop endlessly.
    Jellyfish *jellyfish = Jellyfish::getInstance();
    return true;

}

最後に、解析されたスクリプト:

jellyfish.set( "line_numbers",  true );

問題

アプリケーションを実行すると、getInstance()常に新しい Jellyfish インスタンスが作成されます。しかし、実際の問題は、debug( qDebug() << "test";) を使用した出力で、アプリケーションJellyfish::getInstance();sgmentation fault.

誰かがこれを理解するのを手伝ってくれますか?

4

1 に答える 1

1

これは、Jellyfish コンストラクターが自分自身を再帰的に呼び出すためです。

デバッガーでプログラムを中断すると、次のようなバックトレースが表示されます。

   ...
   Jellyfish::Jellyfish()
   Jellyfish::getInstance()
   Jellyfish::set
   Jellyfish::initScriptEngine() 
   Jellyfish::Jellyfish()
   Jellyfish::getInstance()

問題は、コンストラクターが を呼び出すことJellyfish::getInstance()ですが、オブジェクトが構築されたときJellyfish::instanceはまだ NULL です。

Jellyfish * Jellyfish::getInstance()
{

    if ( !Jellyfish::instance )
    {
        // this line
        // Jellyfish::instance = new Jellyfish();
        // is equivalent to
        Jellyfish * temp = new Jellyfish(); // *
        Jellyfish::instance = temp; // not NULL after construction
    }

    return Jellyfish::instance;

}

コンストラクターから getInstance() を呼び出すと、(segfault まで) 常に無限再帰が発生します。唯一の解決策は、コンストラクターからではなく明示的に Jellyfish::initScriptEngine() を呼び出すことです。

   Jellyfish::getInstance()->initScriptEngine();
于 2012-10-14T20:54:40.417 に答える