2011-10-18 46 views
5

Estoy usando Qt, pero esta es una pregunta genérica de C++. Mi caso es simple, tengo una clase Constants que tiene un miembro estático constante que quiero que se inicialice después de realizar ciertas llamadas a funciones.C++ ¿es posible retrasar la inicialización del miembro estático constante?

constants.h

#ifndef CONSTANTS_H 
#define CONSTANTS_H 

class Constants 
{ 
public: 

    static const char* const FILE_NAME; 
}; 

#endif // CONSTANTS_H 

Constants.cpp

#include "constants.h" 
#include <QApplication> 

const char* const Constants::FILE_NAME = QApplication::applicationFilePath().toStdString().c_str(); 

main.cpp

#include <QtGui/QApplication> 
#include "mainwindow.h" 
#include "constants.h" 
#include <QDebug> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 

    qDebug()<< "name: "<<Constants::FILE_NAME; 
    //for those who are unfamiliar with Qt, qDebug just prints out 
    return a.exec(); 
} 

Al compilar llegué:

QCoreApplication :: applicationFilePath: crea una instancia del objeto QApplication primero

El problema aquí es obvio. Cuando se llama a la función estática de QApplication en Constants.cpp QApplication aún no está instalado por Qt. Tengo que esperar de alguna manera hasta que se pase la línea QApplication a(argc, argv); en main.cpp

¿es posible y, si no, qué más podría sugerir para superar esto?

gracias

+0

¿No lo declara como una constante? Definitivamente no es una constante ya que depende de algún estado en el inicio de la aplicación. – m0skit0

+0

pero necesito que se lea solo cuando se asigna? – destan

+2

Podría estar equivocado, pero 'QApplication :: applicationFilePath(). ToStdString()' me parece temporal, en cuyo caso está almacenando un puntero a datos no válidos. –

Respuesta

7

Una opción es volverlo a partir de una función, manteniéndolo en una variable estática. Esto se inicializará cuando se llame por primera vez a la función.

char const * const file_name() 
{ 
    // Store the string, NOT the pointer to a temporary string's contents 
    static std::string const file_name = 
     QApplication::applicationFilePath().toStdString(); 
    return file_name.c_str(); 
} 
+0

+1. Es aún mejor – Nawaz

+0

Aunque 2 respuestas resultan igual y funcionan bien, su respuesta parece más segura. gracias – destan

+0

Mala idea para devolver un puntero local. – ApproachingDarknessFish

11

solución típica:

#ifndef CONSTANTS_H 
#define CONSTANTS_H 

class Constants 
{ 
public: 

    static const char* const getFILE_NAME(); 
}; 

#endif // CONSTANTS_H 

Y en CPP

#include "constants.h" 
#include <QApplication> 

const char* const Constants::getFILE_NAME() 
{ 
    static const char* const s_FILE_NAME = QApplication::applicationFilePath().toStdString().c_str(); 

    return s_FILE_NAME; 
} 
+0

+1. Simple y correcto. – Nawaz

+3

¿No está almacenando un puntero al contenido de una cadena temporal? ¿O 'toStdString()' devuelve una referencia a algo persistente? –

+0

@Nawaz: incluso el hilo seguro bajo C++ 11 IIRC – sehe

Cuestiones relacionadas