1

I have a class named Jellyfish who use the singleton design pattern :

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

jellyfish.cpp

Jellyfish * Jellyfish::instance = NULL;

Jellyfish * Jellyfish::getInstance()
{

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

    return Jellyfish::instance;

}

When I am in main.cpp and make tests, I have no errors:

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();

}

But I want to use some static methods in Jellyfish in external QScript files :

jellyfish.h

private:

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

jellyfish.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;

}

And finaly the parsed script:

jellyfish.set( "line_numbers",  true );

Problem

When I run the application, getInstance() always creates a new Jellyfish instance. But the real problem is that on the output with debug (qDebug() << "test";) I can see that the application loop on Jellyfish::getInstance(); until I get a sgmentation fault.

Could someone help me to understand this ?

2
  • it would be easier to read the code if it was continuous, not split. could it be that the 'set' method should be non-static? Commented Oct 14, 2012 at 19:13
  • set have to be static (if it is not, Qt seems not be able to detect it) : src/jellyfish.cpp:43:64: erreur: no matching function for call to ‘QScriptEngine::newFunction(<unresolved overloaded function type>)’ But maybe I missunderstood (I'm new in Qt devlopement). cf. doc.qt.digia.com/qt/qscriptvalue.html#setProperty Commented Oct 14, 2012 at 19:18

1 Answer 1

1

It is because your Jellyfish constructor call itself recursively!

Break your program in debugger and you will see backtrace like this:

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

The problem is that your constructor calls Jellyfish::getInstance(), but when object is constructed the Jellyfish::instance is still 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;

}

If you call getInstance() from your constructor then it will always result in infinite recursion (until segfault). The only one solution is to call Jellyfish::initScriptEngine() not from your constructor - but explicit:

   Jellyfish::getInstance()->initScriptEngine();
Sign up to request clarification or add additional context in comments.

1 Comment

I added the call in getInstance with Jellyfish::instance->initScriptEngine() just after constructor. Thanks !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.