2013-08-25 106 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 *静态成员(即全局变量,在类范围内),但这是一个坏主意,原因有很多。这将导致您使用'Q_GLOBAL_STATIC'或指向QImages的指针。 – peppe

回答

2

最干净的方法是:

  1. 使你的类,因为它现在是在应用
  2. 提供一个指针的开始这个类的
  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对象对每个构造函数来说,的确是使用静态方法/对象。单例模式是实现这一点的典型方式,但在你的情况下,问题在于你打电话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; 
} 

现在,你可以在任何地方使用您的图像调用makeInstancedeleteInstance之间使用:

QBoardImages::instance()->empty_white 
+0

非常感谢!这很难过,这是最干净的解决方案..但它运作良好。 – Firzen