我有一个名为Jellyfish的班级使用单身设计模式:
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();
}
但我想在外部QScript文件中使用Jellyfish
中的一些静态方法:
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;
}
最终解析的脚本:
jellyfish.set( "line_numbers", true );
问题
当我运行应用程序时,getInstance()
总是会创建一个新的Jellyfish实例。但真正的问题是在使用debug(qDebug() << "test";
)的输出上,我可以看到应用程序循环Jellyfish::getInstance();
,直到我得到sgmentation fault
。
有人可以帮助我理解这个吗?
答案 0 :(得分: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();