Как обещал продолжаю тему рецептов.
Так как речть в предыдущих статьях в основном шла о библиотеках Qt, то дальнейший код будет приведен с использованием классов из этой библиотеки. Недавно столкнулся с такой задачей: есть приложение, довольное большое. Требуется описать понятие проекта для организации разнообразных файлов и настроек. Таким образом получается некая древовидная структура, например:
Проект
Текстовые файлы
Файл1.txt
Файл2.txt
Файл3.doc
Рисунки
Рис1.jpg
Рис2.bmp
Рис3.png
......
......
Логично что во время выполнения программы должен существовать один единственный проект. В большинстве случаев в такой ситуации используют шаблон Singletone. Да,это не плохое решение, но я пошел немного дальше. Известно, что при написании любой программы на Qt экземпляров класса QApplication также не может быть более одного. Но вернемся к проекту, описать эту абстракцию можно следующим образом:
class QProject // класс проекта
{
public:
Q_DISABLE_COPY(QProject) // блокируем копирование объекта
// добавить файл в проект
void appendFile(const QString& filename)
{
if (!m_filesList.contains(filename))
m_filesList.append(filename)
}
// удалить файл из проекта
void removeFile(const QString& filename)
{
int index = m_filesList.indexOf(filename));
if (index != -1)
m_filesList.remove(index);
}
void load(constQString& filename)
{
........
........
}
void save(constQString& filename)
{
........
........
}
private:
QProject(){} // блокируем конструктор
QStringList m_filesList;
};
Уже любопытно не правда ли? Экземпляр класса QProject невозможно создать никаким образом! Далее пронаследуемся от QApplication:
class QMyApplication : public QApplication
{
public:
QMyApplication(int argc, char *argv[]) :
QApplication(argc, argv)
{}
void createProject();
void closeProject();
QProject *project() const;
private:
QProject m_project; // указатель на проект
};
Пока вроде ничего необычного. А теперь собственно трюк:
class QMyApplication;
class QProject // класс проекта
{
public:
Q_DISABLE_COPY(QProject) // блокируем копирование объекта
// добавить файл в проект
void appendFile(const QString& filename)
{
if (!m_filesList.contains(filename))
m_filesList.append(filename)
}
// удалить файл из проекта
void removeFile(const QString& filename)
{
int index = m_filesList.indexOf(filename));
if (index != -1)
m_filesList.remove(index);
}
private:
QProject(){} // блокируем конструктор
QStringList m_filesList;
friend class QMyApplication;
};
class QMyApplication : public QApplication
{
public:
QMyApplication(int argc, char *argv[]) :
QApplication(argc, argv),
m_project(NULL),
refCount(0)
{
}
void createProject()
{
if (refCount < 1)
{
m_project = new QProject();
}
}
void closeProject()
{
if (refCount > 0)
{
delete m_project;
m_project = NULL;
}
}
QProject *project() const { return m_project; }
private:
int refCount; // счетчик ссылок
QProject m_project; // указатель на проект
};
Что получается: QProject не имеет возможности создать себя сам, однако экземпляр можно создать только через QMyApplication, который по умолчанию Singltone! Таким образом можно гарантировать, что во время работы программы будет создан лишь один единственный экземпляр QProject! Более того, переписав макрос qApp можно получать доступ к проекту из любой точки программы!