2011-10-18 30 views
5

Tôi đang sử dụng Qt nhưng đây là câu hỏi chung C++. Trường hợp của tôi là đơn giản, tôi có một lớp Constants trong đó có một thành viên tĩnh liên tục mà tôi muốn nó được khởi tạo sau khi một số cuộc gọi chức năng được thực hiện.C++ có thể trì hoãn việc khởi tạo thành viên tĩnh không đổi?

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

Khi biên soạn tôi nhận:

QCoreApplication :: applicationFilePath: Vui lòng khởi tạo đối tượng QApplication trước tiên

Vì vậy, vấn đề ở đây là hiển nhiên. Khi chức năng tĩnh của QApplication được gọi trong Constants.cpp QApplication chưa được Qt cài đặt. Tôi cần bằng cách nào đó đợi cho đến khi đường dây QApplication a(argc, argv); được chuyển vào main.cpp

là có thể và nếu không thì bạn có thể đề xuất gì khác để khắc phục điều này?

nhờ

+0

Không tuyên bố đó là hằng số? Nó chắc chắn không phải là một hằng số vì nó dựa trên một số trạng thái lúc khởi động ứng dụng. – m0skit0

+0

nhưng tôi cần nó chỉ đọc khi nó được gán? – destan

+2

Tôi có thể sai, nhưng 'QApplication :: applicationFilePath(). ToStdString()' trông giống như tạm thời đối với tôi, trong trường hợp này bạn đang lưu một con trỏ tới dữ liệu không hợp lệ. –

Trả lời

7

Một lựa chọn là để trả lại từ một chức năng, giữ nó trong một biến tĩnh. Điều này sẽ được khởi tạo khi hàm được gọi đầu tiê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. Nó thậm chí còn tốt hơn. – Nawaz

+0

Mặc dù 2 câu trả lời kết quả giống nhau và hoạt động tốt, câu trả lời của bạn có vẻ an toàn hơn. thanks – destan

+0

Ý tưởng tồi để trả về một con trỏ cục bộ. – ApproachingDarknessFish

11

giải pháp điển hình:

#ifndef CONSTANTS_H 
#define CONSTANTS_H 

class Constants 
{ 
public: 

    static const char* const getFILE_NAME(); 
}; 

#endif // CONSTANTS_H 

Và trong 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. Đơn giản và chính xác. – Nawaz

+3

Bạn không lưu trữ một con trỏ đến nội dung của một chuỗi tạm thời? Hoặc không 'toStdString()' trả về một tham chiếu đến một cái gì đó liên tục? –

+0

@Nawaz: ngay cả chủ đề an toàn dưới C++ 11 IIRC – sehe

Các vấn đề liên quan