2011-10-18 12 views
5

Używam Qt, ale jest to ogólne pytanie w C++. Mój przypadek jest prosty, mam klasę Constants, która ma stały element statyczny, który chcę zainicjować po wykonaniu pewnych wywołań funkcji.C++ czy możliwe jest opóźnienie inicjalizacji stałego elementu statycznego?

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(); 
} 

Podczas kompilacji mam:

QCoreApplication :: applicationFilePath: Najpierw wykonaj instancję obiektu QApplication:

Problem jest oczywisty. Kiedy funkcja statyczna QApplication jest wywoływana w Constants.cpp QApplication nie jest jeszcze instalowany przez Qt. Muszę jakoś poczekać, aż linia QApplication a(argc, argv); zostanie przekazana w main.cpp

czy jest to możliwe, a jeśli nie, to co jeszcze można by przezwyciężyć?

dzięki

+0

Brak deklaracji jako stała? To zdecydowanie nie jest stała, ponieważ opiera się na pewnym stanie przy uruchamianiu aplikacji. – m0skit0

+0

, ale muszę go odczytać tylko po przypisaniu? – destan

+2

Mogę się mylić, ale 'QApplication :: applicationFilePath(). ToStdString()' wygląda jak tymczasowy dla mnie, w takim przypadku przechowujesz wskaźnik do nieprawidłowych danych. –

Odpowiedz

7

Jedną z opcji jest, aby zwrócić go z funkcji, utrzymując ją w zmiennej statycznej. Zostanie on zainicjowany, gdy funkcja zostanie po raz pierwszy wywołana.

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. Jest jeszcze lepiej. – Nawaz

+0

Mimo że 2 odpowiedzi powodują to samo i działają dobrze, twoja odpowiedź wydaje się bezpieczniejsza. dzięki – destan

+0

Zły pomysł, aby zwrócić lokalny wskaźnik. – ApproachingDarknessFish

11

Typowe rozwiązanie:

#ifndef CONSTANTS_H 
#define CONSTANTS_H 

class Constants 
{ 
public: 

    static const char* const getFILE_NAME(); 
}; 

#endif // CONSTANTS_H 

I 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. Prosty i poprawny. – Nawaz

+3

Nie przechowujesz wskaźnika do zawartości tymczasowego ciągu znaków? Czy też 'toStdString()' zwraca odwołanie do czegoś stałego? –

+0

@Nawaz: nawet wątek bezpieczny pod C++ 11 IIRC – sehe