2012-10-14 54 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中添加了调用。谢谢 ! –

相关问题