2013-08-25 2 views
0

У меня есть следующий классСтатический член Qt объектов в C++

class QBoardImages 
{ 
public: 
    QImage empty_white; 
    QImage empty_black; 
    QImage possible_move; 
    QImage lighter; 
    QImage choosed; 
    QImage multiple_move; 

    QImage blue_pawn; 
    QImage blue_queen; 
    QImage blue_skydiver; 
    QImage red_pawn; 
    QImage red_queen; 
    QImage red_skydiver; 

    QBoardImages(); 
}; 

с конструктором, где у меня есть:

QBoardImages::QBoardImages() 
{ 
    QDir::setCurrent(QApplication::applicationDirPath()); 

    empty_white.load("images/board/white.png"); 
    empty_black.load("images/board/black.png"); 
    lighter.load("images/board/lighter.png"); 
    choosed.load("images/board/choosed.png"); 
    blue_pawn.load("images/board/blue_pawn.png"); 
    blue_skydiver.load("images/board/blue_skydiver.png"); 
    blue_queen.load("images/board/blue_queen"); 
    red_pawn.load("images/board/red_pawn.png"); 
    red_skydiver.load("images/board/red_skydiver.png"); 
    red_queen.load("images/board/red_queen.png"); 
    possible_move.load("images/board/possible_move.png"); 
} 

и, конечно, я хочу, чтобы загрузить эти изображения только один раз, но я не могу для этого. Каков наилучший способ загрузки этих изображений только один раз?

Спасибо всем

+2

* "Я хочу, чтобы загрузить эти изображения только один раз, но я не могу это сделать .."* Зачем ? это потому, что вы делаете более одного экземпляра 'QBoardImages' в своем приложении? Если так .. не так ли? – WhozCraig

+0

Да, это так. Но мне просто нужно использовать QBoardImages в нескольких очередях другого класса. Конечно, я мог бы сделать только один экземпляр QBoardImages, но для этого мне понадобилась бы статическая переменная ... Конечно, я мог бы использовать какое-то быстрое и уродливое решение, но я хочу найти что-то элегантное и универсальное. Я нахожу решение аналогичным статическим объектам в Java, например. – Firzen

+0

1) Что именно неправильно с использованием одиночных игр? 2) Вы также можете сделать эти QImages * static * членами класса (т. Е. Глобальные переменные, в области класса), но это плохая идея по ряду причин. Это приведет к использованию 'Q_GLOBAL_STATIC' или указателей для QImages. – peppe

ответ

2

Чистейший подход:

  1. свой класс, как это теперь
  2. Instantiate один объект этого класса в начале приложения
  3. Предоставлять указатель или ссылку на этот объект на любой конструктор других классов, которым нужны эти изображения.

Это будет выглядеть следующим образом, используя ссылки (использование указателей, если вы предпочитаете):

class MyOtherClass1 : // ... 
{ 
public: 
    MyOtherClass1(QBoardImages & boardImages) : 
     boardImages_(boardImages) 
    { 
     // ... 
    } 

private: 
    QBoardImages & boardImages_; 
}; 

class MyOtherClass2 : // ... 
{ 
    // same pattern 
} 

int main(/* ... */) 
{ 
    // ... 

    QBoardImages boardImages; 
    MyOtherClass1 object1(boardImages); 
    MyOtherClass1 object2(boardImages); 

    // ... 
} 

Альтернативный подход, менее чистые, но может быть простым в реализации, так как вы не должны пройти boardImages объект для каждого конструктора, действительно использовать статические методы/объекты. Модели Singleton являются типичным способом реализации этого, но проблема в вашем случае заключается в том, что вы вызываете QApplication::applicationDirPath(), что может быть недоступно в зависимости от того, где вы используете этот класс.

Способ справиться с этим заключается в создании и удалении памяти самостоятельно и убедитесь, что вы используете этот класс только между этими вызовами. Например:

// QBoardImages.h 

class QBoardImages 
{ 
public: 
    static QBoardImages * instance(); 
    static void makeInstance(); 
    static void deleteInstance(); 

    QImage empty_white; 
    // ... 

private: 
    QBoardImages(); 
    static QBoardImages * instance_; 
}; 

// QBoardImages.cpp 

QBoardImages * QBoardImages::instance_ = 0; 
void QBoardImages::makeInstance(){ instance_ = new QBoardImages; } 
void QBoardImages::deleteInstance(){ delete instance_; } 

QBoardImages * QBoardImages::instance() 
{ 
    if(!instance_) 
     makeInstance(); 

    return instance_; 
} 

QBoardImages::QBoardImages() 
{ 
    QDir::setCurrent(QApplication::applicationDirPath()); 

    empty_white.load("images/board/white.png"); 
    // ... 
} 

// main.cpp 

int main(int argc, char ** argv) 
{ 
    QApplication app(argc, argv); 
    QBoardImages::makeInstance(); // make sure to call this 
            // after instantiation of app 

    // ... 

    int retValue = app.exec(); 
    QBoardImages::deleteInstance(); 
    return retValue; 
} 

Теперь вы можете использовать свои изображения в любом месте между звонками makeInstance и deleteInstance помощью:

QBoardImages::instance()->empty_white 
+0

Большое спасибо! Печально, что это чистое решение .. но оно работает хорошо. – Firzen

Смежные вопросы