5

I am using Qt but this is a generic C++ question. My case is simple, I have a class Constants which has a constant static member which I want it to be initialized after certain function calls are made.

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

When compiling I got:

QCoreApplication::applicationFilePath: Please instantiate the QApplication object first

So problem here is obvious. When QApplication's static function is called in Constants.cpp QApplication is not installed by Qt yet. I need to somehow wait until QApplication a(argc, argv); line is passed in main.cpp

is it possible and if not what else could you suggest to overcome this?

thanks

destan
  • 4,301
  • 3
  • 35
  • 62
  • Not declaring it as a constant? It's definitely not a constant since it relies on some state at application startup. – m0skit0 Oct 18 '11 at 11:39
  • but I need it to be read only once it is assigned? – destan Oct 18 '11 at 11:41
  • 2
    I could be wrong, but `QApplication::applicationFilePath().toStdString()` looks like a temporary to me, in which case you're storing a pointer to invalid data. – Mike Seymour Oct 18 '11 at 11:48
  • For example: use an object (like a String class instance), assign it NULL and check if it's NULL (which means it's not assigned yet). – m0skit0 Oct 18 '11 at 12:18
  • You can use `.toAscii()` instead of `.toStdString().c_str()`. – alexisdm Oct 19 '11 at 09:57

2 Answers2

11

Typical solution:

#ifndef CONSTANTS_H
#define CONSTANTS_H

class Constants
{
public:

    static const char* const getFILE_NAME();
};

#endif // CONSTANTS_H

And in 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;
}
sehe
  • 374,641
  • 47
  • 450
  • 633
8

One option is to return it from a function, keeping it in a static variable. This will be initialised when the function is first called.

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();
}
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644