You are on page 1of 9

Contents

General requirements...........................................................................................................................1
Lab work 1. «Buttons and forms»........................................................................................................1
Lab work 2. «Objects and classes»......................................................................................................3
Lab work 3. «Container»......................................................................................................................4
Lab work 4. Part 1 of 2: «Circles on the form»....................................................................................5
Lab work 4. Part 2 of 2: «MVC»..........................................................................................................6
Lab work 5. «С++ objects life-cycle and virtuality»...........................................................................7
Lab work 6. «Vector object editor»......................................................................................................9
Lab work 7. «Grouping and serialization»...........................................................................................9
Lab work 8. «Object tree and subscription».......................................................................................10

General requirements.
 Software requirements:
o code comments, indentation and naming style (PEP 7 or similar) are compulsory;
o console debug output in most methods (L.W. 2,3,5);
 Organization requirements:
o code versioning system (git) is compulsory starting with a second lab work; a
history of commits should be presented at lab work defense;
o https://www.youtube.com/watch?v=9XKwTKz3IgU – a lecture about git.

Lab work 1. «Buttons and forms»


Application type: GUI, desktop; language: any.
Create a simple graphical user interface (GUI) desktop-application in any object-oriented
framework (Visual Studio - Windows Forms Application or WPF; C++ Builder - VCL Application;
С++ and Qt Framework etc.).

 Create a simple GUI application


o form
o main menu, drop-down menu, menu items
o add various standard objects to the form and explore their outlook and behavior
defining properties
 Manage simple events (implement an event reaction to see the even happens)
o mouse clicks, downs, ups and moves
o menu item selection
o key presses, downs and ups
o repaints (how and what for the Paint event exists)
o timer
o resize
 Event management, object connections (an event of one object implements a reaction on
another object).
 Event-handler management: one event handler on multiple objects and events (e.g. three
different buttons sharing the same handler that changes the color of the button pressed),
program event handler invocation (calling event handler from the code), program event
invocation (calling methods PerformClick and similar).
 Design time and runtime property management: identify two main properties of each class
and learn to change them both in runtime and design time.
 Study all general-purpose controls (learn the purpose and the behavior) of the environment
you have selected:
o if Visual Studio - Windows Forms Application: all controls from «General», and
«Containers» tabs, with menu and timer controls added
o if C++ Builder - VCL Application: all controls from «Standard», «Additional»,
«Win32» and «System» tabs
o otherwise any similar set of controls
 For each of the standard controls from the previous item it is necessary to study its purpose
(typical use) and the main property or two. For example, a text box is used to enter and store
a string value, thus its main property is the property storing the current string value. The
main property of the drop-down combobox is the property storing the list of possible values
and the index of the selected value, etc. Learn to manipulate each objects’ main property
both in runtime and design time.
 Dynamic creation and deletion of interface objects:
o create new interface objects and a reaction of interface events: e.g. clicking a mouse
on the form should create a new button where the mouse was clicked; this newly
created object must manage at least one event of its own.

During the lab work the student must learn:


 how classes differ from objects;
 how the application interface is composed of standard GUI controls;
 how GUI controls properties are changed in runtime and design time;
 how objects call methods of other objects;
 when and how standard events occur.

The application should contain no less than 15 various interacting controls (all of different classes).
The student must be able to implement required program changes at once by the teacher’s request of
“Mouse hovering over this object should produce that action on that object” or similar.

Main controls to pay special attention to are the following: a button (title, button press event),
textbox (text, text change event), dropdown combobox (text, list of dropdown elements, selected
element index, selected), static text (text), checkbox (text, check state, check state change event),
radio button (text, check state, check state change event), panel (size), spacer (alignment), list box
and check list box (elements, elements selection event), tabs (active tab, active tab change event)
etc.

The main goal of the first lab work is to learn how to create GUI event-driven applications. The
application to achieve that purpose must be as diverse as possible. The sense, reason and the
meaning of the application are not required. Even more, they interfere and impede the main goal.
Do not try to implement anything useful! Put as many different controls and learn how they interact,
change each other’s properties, call each other’s methods and react on different events.

Tutorial is here: https://www.youtube.com/watch?v=BEmQpbVHjwg

Lab work 2. «Objects and classes»


Application type: console; language: c++.
Define and implement some classes and write a program to illustrate how you can use them. Add
console debug output in most methods (especially constructors and destructors).

Lab work may consist of several projects within the same solution. Do not put lots of code into the
same file or implement the task sequentially. I’d be wise to start with definition and implementation
of a simple class, then learn and try to create several instances statically and dynamically, learn to
access its properties and methods. Then declare constructors and destructors and test them. After
that create a descendant class and learn to instantiate it. Learn to declare new methods and redeclare
existing in descendant classes and so on. Do not try to define or redefine here some standard
operators (like ++, <<, >> и т.д.)!
Recommended objects to manipulate: geometric shapes (points, sections, circles and ellipses),
mathematical objects (vectors and matrices) etc.
Not recommended objects to manipulate (as the teacher has little knowledge of this subject area):
Warrior, Weapon, HP, Damage, etc.

 Definitions
o classes
o attributes, methods
o descendant classes
o constructors (necessary at least: default without parameters, with parameters, copy
constructor), destructor
o visibility/accessibility modifiers (illustrate private, protected and public)
 Implementation
o methods
o inside definition, after definition
o constructors, destructor
 Object creation and usage (attribute access, methods invocation)
o statically created objects («MyClass obj;»)
o dynamically created objects («MyClass *obj = new MyClass();»)
o create objects with different constructors (each class must implement 3 constructors:
default, with parameters, copying)
o placing objects into variables of different type (explain how MyBase * obj = new
MyBase() differs from MyBase * obj = new MyDeriv())
o descendant objects creation (illustrate which constructors are invoked)
o object composition: attribute of one class is an object or a pointer to the object of
another class; composed object is created on its parent creation and deleted on its
parent deletion; illustrate the difference between composing another object directly
or a pointer to another object.
 Object deconstruction
o for statically created objects
o for dynamically created objects
o of descendant classes objects (illustrate which destructors are invoked)

Lab work requires confident understanding and management of pointers and references. Students
must clearly understand everything the following code does: MyBase * obj = new MyDeriv() (a
pointer variable is created first, a new object is created in the heap later, and its address is put into
the pointer variable).

Lab work requires to implement enough examples to understand the following situations:
 an ancestor class has both the constructor and the destructor, a descendant class has neither;
what happens on ancestor object creation, on a descendant object creation?
 an ancestor and a descendant classes have both the constructor and the destructor: in which
order are they invoked on ancestor and descendant object creation?
 A pointer variable of a base type receives an address of a descendant class object: which
methods are accessible for this variable?

Additional information: https://www.youtube.com/watch?v=g5kurT3ZCSg


Lab work 3. «Container»
Application type: console; language: any.
Define and implement a storage for various objects (descendants of the same ancestor). Implement
the code to illustrate its typical usage. A storage should be as universal as possible, it should allow
to store any future objects to be created. If you know how to use templates, go on, use them. If not,
do not even try, make a storage of base class pointers instead, only make this base class as generic
as possible.
The storage mission is to store objects. Think well about the way you could use it, about typical
operations on the storage and its objects.

 Storage functions
o add an objects
o remove an objects (with object deconstruction and without)
o iterating over objects if applicable (current, next, previous, accessibility checks)
o accessing object by index, if applicable
o iterating over objects to invoke a method on each
 Main program should implement the code that randomly:
o creates new objects
o adds new objects to the storage
o performs some simple actions on the objects
o removes objects from the storage

The storage must be implemented as a separate object to be created and manipulated in the main
program. The storage should act (look like) either as an array, or as a list (choose as you prefer).
The storage should be implemented inside either as an array, or as a list (choose as you prefer).
Student must be aware of the difference between two last sentences. Main program should illustrate
storage usage and run a cycle of 100, 1000 and 10000 random actions measuring time. Action
should be selected from the following list: create an object and insert it into a random position;
remove and deconstruct a random object from the storage; select a random object from the storage
and run its method.

For array-looking storages main program should include the code similar to:

// create a storage
MyStorage storage(10);
// add objects
for (int i=0; i<storage.getCount(); i++)
storage.setObject(i, new SomeObject());
// iterate over objects
for (int i=0; i<storage.getCount(); i++)
storage.getObject(i).someMethod();

For list-looking storages main program should include the code similar to:

// create a storage
MyStorage storage();
// add objects
for (int i=0; i<10; i++)
storage.add(new SomeObject());
// iterate over objects
for (storage.first(); !storage.eol(); storage.next())
storage.getObject().someMethod();
The storage should handle random adding, deleting and counting storage object, keeping track of
empty positions in the storage if any, and dynamically resize to fit all necessary objects. If you are
not easy with linked lists, do not use them. If you are not easy with templates, do not use them. STL
containers are not allowed, since the idea of the lab work is more or less to replicate them.

Lab work 4. Part 1 of 2: «Circles on the form»


Application type: GUI; language: any.
 Create a simple GUI application with:
o a definition of a simple CCircle class with coordinates and a constant radius;
o a storage from L.W.3 to store a collection of CCircle instances;
o a form with an object to paint on (e.g. PaintBox)
 Implement the following behavior:
o a mouse click on the form creates a CCircle instance at the mouse click position and
places it into the storage;
o Paint event draws all CCircles of the storage on the form.
o LMB (left mouse button) click selects the CCircle under the cursor, which becomes
“selected” and draws differently
o LMB clicks with Ctrl button pressed select several objects
o Del button presses delete all selected circles.

Please, ensure appropriate encapsulation level of CCircle. The CCircle object must be responsible
for drawing its graphical representation on the screen as well as for checking if the coordinates of
the mouse click fall inside it. Hardly for any reason should the coordinates of CCircle be made
public.

Lab work 4. Part 2 of 2: «MVC»


Application type: GUI; language: any.
 Create a simple GUI application with:
o three integers A, B and C ranged from 0 to 100;
o each integer is represented and edited in three different controls: textBox,
numericUpDown and trackBar (or analogs in other frameworks);
o if an integer is edited, its value changes in all its controls;
o B should never be less than A and greater than C (enforcing condition A<=B<=C);
o values A, B and C should be kept between application runs;
 An application must employ MVC pattern:
o three integers must be stored in a separate ‘model’ object;
o all changes and checks should be hid inside the model;
o the model should be responsible for keeping the values between application runs;
o controls for A and C must implement cascading behavior: the value entered by the
user should always be stored and all other values changed to ensure the condition;
o controls for B must implement restricting behavior: the value entered by the user
should be rejected if it breaks the condition.
 Sample application design might look like:
Additional information: https://www.youtube.com/watch?v=q0OsToAZzPI

Lab work 5. «С++ objects life-cycle and virtuality»


Application type: console; language: c++.
Declare and implement several classes and implement a main function to show typical usage
patterns. Lab work might consist of several programs for better readability.

 Definitions
o redefined methods (implement the code to show when a redefined or inherited
method is invoked);
o virtual and overridden methods including destructors (implement the code to show
when an overridden or base method is invoked);
 Implementation
o type checking (check if an object belongs to a certain class, or to a certain class and
all its descendants: “classname” vs. “isA” functionality);
o safe typecasting with dynamic_cast
o safe typecasting with self-implemented “isA” functionality
 Passing objects into the functions and returning objects as function results, with lifecycle
control;
 Smart pointers unique_ptr and shared_ptr, the way they influence the object lifecycle.

During the lab work the student must learn:


 the purpose and workflow of virtual methods, constructors and destructors;
 suppose the base class method1 invokes non-virtual method2, redefined in the descendant
class; what happens if method1 is invoked for the instance of the descendant class?
 suppose the base class method1 invokes virtual method2, redefined in the descendant class;
what happens if method1 is invoked for the instance of the descendant class?

Illustrate with the code and learn:


 the purpose of virtual methods;
 the reason of storing the object in a variable of a base class;
 the purpose of type checking;
 the purpose of safe typecasting.

Illustrate with the code:


 declare and implement a base virtual method string classname(), override in
descendants, test and find out usage problems;
 declare and implement a base virtual method bool isA(string classname), override in
descendants, test and illustrate the difference from classname() method.

Demonstrate unsafe typecasting and type checking with self-made isA method. Demonstrate
standard language typecasting features (dynamic_cast in c++ or analog in other languages).

To test object passing into the function, the following functions should be implemented:
void func1(Base obj) { ... };
void func2(Base *obj) { ... };
void func3(Base &obj) { ... };

Create a simple Base class and its descendant Desc, implement all three constructors and a
destructor for both of them:
Base() { ... };
Base(Base *obj) { ... };
Base(Base &obj) { ... };
~Base() { ... };

Desc() { ... };
Desc(Desc *obj) { ... };
Desc(Desc &obj) { ... };
~Desc() { ... };

Create Base and Desc instances and pass them into all three functions, explain constructors and
destructors debug output.

To test object returning from the function, the following functions should be implemented:
Base func1() { ... };
Base* func2() { ... };
Base& func3() { ... };

Implement all three functions in two variations: with static and dynamic object instance creation.
Place the result of each function into the local variable and explain constructors and destructors
debug output. Identify evident and possible memory management problems.

In order to learn and illustrate the behavior of smart pointers, create several instances of
unique_ptr and shared_ptr (with and without make_unique and make_shared) and check the
lifecycle.

Lab work 6. «Vector object editor»


Application type: GUI; language: any.
Start with L.W.4 and implement a simple vector object editor (circle, rectangle, triangle, section,
etc.) with the following functionality:
 Object creation:
o a menu, a toolbar with available objects and actions;
o new object created with a mouse or a keyboard;
 Object manipulation:
o selecting an object to manipulate with a mouse or a keyboard;
o color, size and location changing;
o object deletion
o object should always be inside of the working area
 Code requirements:
o mouse and keyboard manipulation;
o «reasonable» classes hierarchy;
o storage from L.W.3
o logic from user-interface separation in an MVC style from L.W.4.

Lab work 7. «Grouping and serialization»


Application type: GUI; language: any.
Start with L.W.6 and elaborate:
 Grouping and ungrouping of objects and groups (grouped objects behave like a single
object) with Composite pattern implementation:
o several objects in the working area are selected, extracted from the storage, placed
into the special CGroup object and put back into the storage;
o the group behaves as a single object, keeps relative distances between its
components, does not leave the working area, etc.;
o the group may include other groups;
o the group should not depend on specific object classes;
 Saving and restoring the storage from L.W.3 to and from the text file with either Abstract
Factory or Factory Method patterns:
o all storage objects are placed into a human-readable text file;
o filename selection with standard openfile and savefile dialogs;
o saving and restoring routines should not depend on specific object classes.
 Additionally:
o objects manipulations with a mouse, not only keyboard;
o user interface actions implemented with Command pattern (with undo functionality);
o user interface actions and new specific types with dynamically linked libraries
(DLL).

The storage saving and loading functions should not know any specific object details. All they
should do is invoking save() and load() methods of specific objects to delegate them the writing and
reading from file.

Storage-to-file serializing code should follow the following scheme:


 Open the file for writing
 Store the number of objects
 For each storage object:
o Invoke object’s method save()
 Close the file

Storage-from-file deserialization is a bit tricky. Each object, evidently, has both save() and load()
virtual functions. However, in order to be able to call load() method, the object has to be created
beforehand! Which class should be instantiated, to call the load() method? It is exactly the problem
the Abstract Factory or Factory Method patterns aim to solve.

Storage-from-file deserialization code should follow the following scheme:


 Open the file for reading
 Read the number of objects
 Iterate the following code that many times:
o Read the class marker from the file
o Create and object of that class
o Invoke the object’s method load()
 Close the file

Lab work 8. «Object tree and subscription»


Application type: GUI; language: any.
Start with L.W.7 and elaborate:
 Add a TreeView to the form to show the contents of the storage
 Synchronize the TreeView with the storage using the Observer pattern: when the object is
selected in the tree, it should become selected in the working area and vice versa.
 Using the Observer pattern implement a special «sticky» object: when other objects touch
the «sticky» object, they «stick» to it and move along with it.

The TreeView object should learn to rebuild itself from the current storage contents of specific
objects and groups of objects and groups. That is usually achieved with a recursive function
processNode(TreeNode tn, StorageObject o) with the following typical behavior:

processNode(TreeNode tn, StorageObject o)


{
Create a new child node t for the current node tn;
If object o is a group, then:
For each object oo from the group:
invoke processNode(t, oo);
}

Additionally:
 Ensure all application and user interface actions are performed only though commands
(including object creation and deletion, including mouse-invoked commands), with undo
functionality and user-visible history stack.
 Implement a property window to check and to change selected objects properties though
introspection and reflection.

You might also like