UNISA Chatter – Design patterns in C++ Part 1: Visitor Pattern
See UNISA – Summary of 2010 Posts for a list of related UNISA posts. This post is one of the summary posts I will be building up over the next couple of months, so if you are following this topic or completing the same course as I this year, you may want to bookmark this post and come back occasionally for a peek and to give “candid” feedback.
This course is based on QT4 (https://en.wikipedia.org/wiki/Qt_(toolkit)), which made me cringe as I am heavily into and in love with Visual Studio 2010. After spending several evenings unzipping tar’s, battling to find instructions on installation, setup and dependencies, followed by a dismal experience in the IDE we are forced to use for this course and having to build everything (libraries, utilities, …) myself, I yearn to get back into Visual Studio and the near seamless installation experience.
The funny part is that while I setup this special development environment, I must have installed and configured the Team Foundation Server and Visual Studio environment in excess of 25 times using our VM Rangers factory … few clicks and it works, compared to a few hours slog every evening … but nevertheless, something new every day keeps the boredom away I guess.
What is really fun, is the short return to C++, after years of C# distractions :)
QT and Environment Summary
Terminology | Description | Example |
Makefile | The makefile contains the instructions, such as rules for building files, target executables and dependencies. The utility make is used to manage the building of the project using the makefile as the treasure map or build recipe. | See https://blogs.msdn.com/willy-peter_schaub/pages/unisa-makefile-example.aspx for an example. |
Project File | Project file describes the project by listing all files, options and other information needed to build the project. | TEMPLATE = app | lib SOURCES += sample.cpp |
QApplication | Main application object needed by all Qt GUI applications. Typically created at the start of the main() function. | |
QMake | Qt tool that can be used to generate makefiles based on a project file. | |
QString | Dynamic Qt string implementation class with support for Unicode. | |
TEMPLATE | Defines which templated makefile to use, i.e. app for application, lib for library. | TEMPLATE = app | lib SOURCES += sample.cpp |
Design Pattern Summary
Terminology | Description |
Design Patterns | You best refer to the book “Gang of Four” for the complete story. In essence we have three main categories of patterns that define a name, a description, an abstract description of the design problem and discussion on pros and cons of patterns:
|
Pattern: Visitor |
|
Example of the CodeVisitor class, which is an extension of the FileVisitor, as implemented in the Ezust Utilities. See Qt – Cross-platform application and UI framework for more information.
Header File
1: #ifndef _CODE_VISITOR_H_
2: #define _CODE_VISITOR_H_
3:
4: #include <filevisitor.h>
5: #include <QStringList>
6:
7:
8: /**
9: This program will visit every selected file
10: in or below the specified directory and produce a list
11: of the names and optionally the file size.
12: */
13: //start
14: class CodeVisitor : public FileVisitor {
15: public:
16: CodeVisitor(QString filter = "*", bool recursive = true, int displayType = 0, bool verbose = false):
17: FileVisitor(filter,recursive){}
18: CodeVisitor(QStringList filterList = "*", bool recursive = true, int displayType = 0, bool verbose = false);
19: void processFile(QString filename);
20: QString getResultString() const;
21: int getNumFiles() const;
22: QString getFileSizeInfo(QString filename) const;
23: private:
24: int m_NumFiles;
25: int m_DisplayType;
26: bool m_Verbose;
27: QStringList m_Result;
28: };
29: //end
30: #endif
Source File
1: #include "codevisitor.h"
2: #include <QDebug>
3: #include <QFile>
4: #include <QTextStream>
5:
6:
7: CodeVisitor::CodeVisitor(QStringList filterList, bool recursive, int sizing, bool verbose) :
8: FileVisitor(filterList, recursive)
9: {
10: m_NumFiles = 0;
11: m_DisplayType = sizing;
12: m_Verbose = verbose;
13: }
14:
15: //start id="processfile"
16: void CodeVisitor::processFile(QString filename) {
17: QString tempOutput = filename;
18:
19: // First check if we have a token and if yes, if file matches
20: if ( m_Verbose )
21: {
22: tempOutput.append(" \t");
23: tempOutput.append(getFileSizeInfo(filename));
24: }
25:
26: // Increment files processed
27: ++m_NumFiles;
28:
29: // Move stuff to output
30: m_Result << tempOutput;
31: }
32: //end
33:
34: QString CodeVisitor::getResultString() const {
35: return m_Result.join("\n");
36: }
37:
38: QString CodeVisitor::getFileSizeInfo(QString fileName) const {
39: QFile file(fileName);
40: QFileInfo fileInfo(file);
41: QString fileSize;
42: double size = fileInfo.size();
43: if ( m_DisplayType == 2 )
44: {
45: size = size / 1000000;
46: fileSize = QString("size: %1 megabytes").arg(size);
47: }
48: else
49: if ( m_DisplayType == 1 )
50: {
51: size = size / 1000;
52: fileSize = QString("size: %1 kilobytes").arg(size) ;
53: }
54: else
55: {
56: fileSize = QString("size: %1 bytes").arg(size) ;
57: }
58: return fileSize;
59: }
60:
61: int CodeVisitor::getNumFiles() const {
62: return m_NumFiles;
63: }
Sample Output
Test Arguments –> -d c:\temp\subdirectory -v -k
Files Processed: 12
C:/temp/subdirectory/AcGenral.dll size: 2175.49 kilobytes
C:/temp/subdirectory/AcLayers.dll size: 559.616 kilobytes
C:/temp/subdirectory/AcRes.dll size: 2.56 kilobytes
C:/temp/subdirectory/AcSpecfc.dll size: 474.112 kilobytes
C:/temp/subdirectory/AcXtrnal.dll size: 211.968 kilobytes
C:/temp/subdirectory/apihex86.dll size: 41.984 kilobytes
C:/temp/subdirectory/drvmain.sdb size: 151.136 kilobytes
C:/temp/subdirectory/msimain.sdb size: 1757.98 kilobytes
C:/temp/subdirectory/pcamain.sdb size: 37.358 kilobytes
C:/temp/subdirectory/sysmain.sdb size: 3932.71 kilobytes
… next we will explore the QObject … the mother of all Qt widgets.