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 并进行测试时,我没有错误:

主文件

#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() ,那么它将始终导致无限递归(直到段错误)。唯一的解决方案是不从您的构造函数调用 Jellyfish::initScriptEngine() - 而是显式调用:

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