2012-10-14 56 views
1

我有一個類名爲水母誰使用Singleton設計模式:Call對象實例從C++通過腳本調用的函數

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; 

} 

當我在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文件:

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; 

} 

而且finaly解析腳本:

jellyfish.set("line_numbers", true); 

問題

當我運行應用程序,getInstance()總是創建一個新的水母實例。但真正的問題是,在調試的輸出(qDebug() << "test";)我可以看到應用程序循環Jellyfish::getInstance();,直到我得到一個sgmentation fault

有人能幫我理解嗎?

+0

它會更容易閱讀的代碼,如果它是連續的,不分裂。那麼'set'方法應該是非靜態的嗎? –

+0

集必須是靜態的(如果不是,Qt似乎無法檢測到它):'src/jellyfish.cpp:43:64:erreur:沒有匹配函數調用'QScriptEngine :: newFunction(<未解析的重載函數類型>)''但是也許我錯過了理解(我是Qt新手)。比照http://doc.qt.digia.com/qt/qscriptvalue.html#setProperty –

回答

1

這是因爲你的水母構造函數遞歸調用自己!

調試器打破你的計劃,你會看到回溯這樣的:

... 
    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(),那麼它總是會導致無限遞歸(直到出現段錯誤)。唯一的一個解決方法是調用水母:: initScriptEngine()不是從你的構造 - 但明確:

Jellyfish::getInstance()->initScriptEngine(); 
+0

我在構造函數後面用'Jellyfish :: instance-> initScriptEngine()'在getInstance中添加了調用。謝謝 ! –

相關問題