Sie sind auf Seite 1von 24

System Design (1010/1039) / MSE Prof. P. Fromm / Prof. M.

Lipp
Exam System Design (1010/1039) / MSE
(Prüfungsleistung) WS2013/14 A (10.02.14)
Support Material  UML Reference List

Remarks  Please check immediately if all pages of the exam (24) + UML
reference list are available
 Duration: 180min
 Enter your name, Matr.-Number on the first page and sign it
 Write legible! Hard to read writing will not yield any points.
 Don’t use a pencil.
 Keep the pages stapled together.
 If you finish within the last 15min of the exam, please stay
seated to avoid disturbing your colleagues.

Name SOLUTION

Matr.-Number

Signature

Max. Points Achieved Points


1. Knowledge Corner 15
2. Extending the Navi System 35
3. Lawn Sprinkler System 30
4. Template Class 20

Total Points Exam 100

PO 2006 Calculation

Scaled exam points 80


Scaled lab points 20
Total 100

Mark: ________

Page 1 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

1 Knowledge Corner (15)


For the following questions, only one answer is right or the best answer. Marking:
Correct answer: + points
No answer: 0 points
Wrong answer: - points

[2] Protected attributes in a class can be accessed…

By own methods and derived class methods

By derived class methods and friend functions


x
By own methods, derived class methods and friend functions

[3] An abstract base class…


x
Contains only pure virtual methods and often serves as an interface specification for
derived classes

Contains virtual and non-virtual methods and usually contains common methods for
derived classes

Contains only pure virtual methods, a pure virtual constructor and destructor and often
serves as an interface specification for derived classes

[2] UML stands for…

Uniform modelling language


x
Unified modelling language

United modelling language

[2] State machines can be used…

To describe reactive systems, which have more than one user input and react differently
on every input.

To describe reactive systems, which have more than one operational mode and more
than one user input and depending on the mode react differently on the user input.
x
To describe reactive systems, which have more than one operational mode and
depending on the mode react differently to events.

Page 2 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

[2] C1 code coverage…

Checks, if every non-empty decision in a program is being covered

Checks, if every path combination in a program is being covered


x
Checks, if every decision path in a program is being covered

[2] A good test process consists of…


x
Test planning, testcase specification, test execution, test reporting, test management

The highest possible number of functional and non-functional (C0, C1) tests

Enough testcases, to prove that the program does not contain any bugs

[2] The difference between malloc and new is…

new is used for allocating memory for C++ objects, malloc is used for normal variables
x
new provided a typed-pointer to the allocated memory, malloc does not

new calls the default constructor when allocating dynamic memory, malloc does not
initialize the allocated memory

Page 3 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

2 Extending the navigation system (35)


In the lab we have designed a rather inelegant implementation of a route, by providing different
containers for the waypoints and the points of interest of the route. A better implementation would
be the following polymorph design:
- All waypoints and POI’s are stored in separate databases
- The route itself is stored in a single common container, which contains both the waypoints
and the POI’s in the order the driver will reach them (sketch below).

x
o x

o
x
x
x – Waypoints
Route o – Points of Interest

2.1 Class relations (10)


Add all class relations to the diagram below. Do not forget the multiplicities. Note: Not all attributes
are displayed!

Page 4 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

Page 5 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

2.2 Data Containers (5)


You decide to use STL containers for storing the waypoints, points of interests and the route.
Which container types are the best choices considering the following requirements:
- The waypoints and Poi’s shall be identified by their name
- For the route, first the waypoints will be added and afterwards the Poi’s will be inserted

Class Attribute declaration (e.g. Explanation of your choice


vector<int>)

CRoute List<CWaypoint*> (or map List allows fast insertion. Pointer due to
<string, CWaypoint*>) polymorph approach

CWpDatabase map<string, CWaypoint> Map with string for identification (fast lookup)

CPoiDatabase map<string, CPoi> Map with string for identification (fast lookup)

2.3 Implementation addPoi (5)


Provide the code for void CRoute::addPoi(string namePoi, string afterWp), fulfilling
the following requirements
- The Poi with the name namePoi shall be inserted after the waypoint having the name
afterWp. Hint: Check the cheat sheet at the end of the exam.
- The following errors have to be considered (cout an appropriate error message, do not
change the route in this case)
o Database(s) not connected
o Poi not found
o Waypoint not found
- Illegal pointers have the value 0

Page 6 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

void CRoute::addPoi(string namePoi, string afterWp)


{
// 1 for getting the CPoi Pointer
// 3 for correct location of the insert position
// 1 for correct error handling (Null Pointer etc.)
CPOI* p = m_pPoiDatabase->getPointerToPoi(namePoi);
list<CWaypoint*>::iterator i;

if ((m_pWpDatabase != 0) && (p != 0))


{
for (i = m_pRoute.begin(); i != m_pRoute.end(); ++i)
{
if ((*i)->getName() == afterWp)
{
cout << "Found Waypoint" <<endl;
list<CWaypoint*>::iterator pos = i;
m_pRoute.insert(++os,p);
return;
}
}

}
else
{
cout << "WP-DB not connected or WP not found" << endl;

cout << "Waypoint not found" << endl;


}

2.4 Implementation set (10)


Provide the code for the function void CWaypoint::set(string name, double
latitude, double longitude), fulfilling the following requirements:

- The name parameter will be written to the attribute m_name


- The latitude and longitude parameter will be written to the corresponding attribute, if both
are in the valid range (represented by the constants MINLAT, MAXLAT, MINLONG,

Page 7 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

MAXLONG). In case one of the parameters is not in the valid range, both values will be set to
0 and the corresponding exception enum wp_exception {LATTITUDEOUTOFRANGE,
LONGITUDEOUTOFRANGE} will be thrown.
Provide the code for the method and testcode, which will ensure a 100% C0 and C1 coverage of
your method. Note: In case an exception is thrown, print an error message “ERROR: Longitude out
of range” or “ERROR: Latitude out of range”. In case the assignment was ok, print “OK”;

void CWaypoint::set(string name, double latitude, double longitude)


{
//5 in Total
// 1 for normal attributes
// 2 for latitude check and exception and correct assignment
// 2 for longitude check and exception and correct assignment

m_name = name;
m_latitude = 0;
m_longitude = 0;

if (latitude < -90 || latitude > 90)


{
throw LATTITUDEOUTOFRANGE;

if (longitude < -180 || longitude > 180)


{
throw LONGITUDEOUTOFRANGE;
}
else
{
m_longitude = 0;

m_latitude = latitude;
m_longitude = longitude;
}

Page 8 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

//Testcases
//1 point per group (3 total)
// 2 point for correct catch
//Note: catch structure may be described as copy and paste

CWaypoint wp;
try
{
wp.set("wpwronglongitude",50,500);
cout << "Assignment ok" << endl;
}

catch (wp_exception& e)
{
switch (e)
{
case LATTITUDEOUTOFRANGE : cout << "ERROR: wrong lattitude" << endl; break;
case LONGITUDEOUTOFRANGE : cout << "ERROR: wrong longitude" << endl; break;
default: "OPPS"; break;
}

try
{
wp.set("wpwronglattitude",500,50);
cout << "Assignment ok" << endl;
}

catch (wp_exception& e)
{
switch (e)
{
case LATTITUDEOUTOFRANGE : cout << "ERROR: wrong lattitude" << endl; break;
case LONGITUDEOUTOFRANGE : cout << "ERROR: wrong longitude" << endl; break;
default: "OPPS"; break;
}

try
{
wp.set("ok",50,50);
cout << "Assignment ok" << endl;
}

Page 9 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

catch (wp_exception& e)
{
switch (e)
{
case LATTITUDEOUTOFRANGE : cout << "ERROR: wrong lattitude" << endl; break;
case LONGITUDEOUTOFRANGE : cout << "ERROR: wrong longitude" << endl; break;
default: "OPPS"; break;
}

Page 10 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

2.5 Compilerwarning (5)


When compiling your code, you get the following warning:
Class '[C@585b4e3d' has virtual method 'print' but non-virtual destructor in
CWaypoint.h

Why do you get this message?


CWaypoint doen not have a virtual destructor but some virtual methods, which allow a polymorph
use of this class. So in case a derived object is destroyed using a polymorph base object, the
destructor of the derived object will not be called.

Is it safe to ignore this message? Explain!


No, because the destructor of the derived object may contain some important clean-up code.

Page 11 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

3 Lawn Sprinkler System (30)


We want to design an advanced lawn sprinkler system. We have the following requirement
description:
The system has a push button for turning it on and another one for turning it off. When turned on,
the system will spread water on the lawn for 15 minutes. After that, it stops for 5 minutes. Then it
checks the value of a humidity sensor. When the value is below 30, it spreads water again for 15
minutes and then waits 5 minutes and so on until the humidity reaches the required value of 30. Of
course, you can turn the system off any time.

3.1 Activity diagram (5)


Draw an UML activity diagram that describes the behavior of the system after it has been turned on
and runs normally (i. e. is not turned off manually). Remember that descriptions of activities must
include a verb. Observe the formal rules for UML activity diagrams.

Page 12 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

Page 13 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

3.2 Implementation
You are now to implement the controller for the lawn sprinkler system. There is already an
interface class for the controller and some predefined actor and sensor classes.

The sprinkler valve can be turned on and off by invoking the appropriate methods. The timer can
be started with the specified number of minutes. When the time has elapsed, the timer sends the
event “evExpired” to its associated controller. The timer can be cancelled at any time by invoking
its cancelTimer() methods. Note that invoking startTimer() when the timer already runs is
illegal and results in undefined behavior of the timer.
The lawn sprinkler system is started when the start button is pushed which results in an event
“evStart” being sent to the controller (i. e. handleEvent(“evStart”) is invoked). At any time,
the stop button can be pushed which causes “evStop” to be sent to the controller (i. e.
handleEvent(“evStop”) is invoked) which must stop the system immediately.

3.2.1 State diagram (10)


Draw a UML state diagram for the controller. Use states “Off”, “Sprinkling” and “Pausing”. In order
to keep the diagram readable, complete the table (next page) that defines abbreviations for the
actions. If you have several actions in one transition, separate their abbreviations with a comma.
Avoid redundant actions (e. g. turning off the valve although it is already known to be off). Observe
the formal rules for UML state diagrams.

Page 14 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

Action Short name Code to be executed

valveOn m_valve->on()

Diagram:

Remarks:
 The diagram above (being created with Together) does not use abbreviations for actions.

Page 15 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

3.2.2 Implement Class CController (10)


Provide your own implementation of a controller class (both class definition and method
implementations). Define an enum-type for the states and use the “switch(state)” pattern from the
lecture (not using the pattern results in 0 points).
Note that it is not sufficient to provide an implementation of method handleEvent() in order to
get a useable controller implementation.

class MyController: public CController {


enum State { OFF, SPRINKLING, PAUSING };

private:
State m_state;

public:
MyController(CSprinklerValve* valve, CHumiditySensor* hSensor);
void setTimer(CTimer* timer);

void handleEvent(std::string event);

};

MyController::MyController(CSprinklerValve* valve, CHumiditySensor* hSensor) {


m_valve = valve;
m_sensor = hSensor;
m_timer = 0;
m_state = OFF;
}

void MyController::setTimer(CTimer* timer) {


m_timer = timer;
}

Page 16 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

void MyController::handleEvent(string event) {


switch (m_state) {
case OFF:
if (event == "evStart") {
m_valve->on();
m_timer->start(15);
m_state = SPRINKLING;
}
break;

case SPRINKLING:
if (event == "evStop") {
m_valve->off();
m_timer->cancel();
m_state = OFF;
break;
}
if (event == "evExpired") {
m_valve->off();
m_timer->start(5);
m_state = PAUSING;
}
break;

case PAUSING:
if (event == "evStop") {
m_timer->cancel();
m_state = OFF;
break;
}
if (event == "evExpired") {
if (m_sensor->getValue() < 30) {
m_valve->on();
m_timer->start(15);
m_state = SPRINKLING;
break;
}
m_state = OFF;
}
break;
}
}

Page 17 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

3.3 Operator overloading (5)


Your colleague considers it clumsy to invoke controller.handleEvent("event"). He wants
to be able to just write controller << "event" when he wants to send an event to the
controller. Sending two events with controller << "event1" << "event1" should also
work. Provide the required additions to your class definition and an implementation (outside the
class definition).

Header:

CController& operator<< (std::string event);

Implementation;

CController& CController::operator<< (string event) {


handleEvent(event);
return *this;
}

Page 18 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

4 C++ Templates (20)


Your task is to implement a template ringbuffer class, which allows you to store any kind of data
object by aggregation(!). A ringbuffer is implemented as a FIFO buffer. The following class diagram
shows the general structure of the design.

The operation of the ringbuffer is illustrated in the picture below

Write Pointer m_idxWrite

element
element

element
0
Physical implementation
Read Pointer
m_idxRead m_pBuffer
element
0 element
element
element
m_pBuffer

Detailled Requirements:
 The constructor creates an array of the required size. The memory for the elements will
not be allocated yet. All pointers will be initialized to 0. The index values as well as the
filling level will be set to 0.
 The write operation writes a data element to the next free location. If no memory for this
element has been allocated yet (i.e. first round of the buffer), the memory will be allocated
and the content of the data element will be copied by the copy constructor. If memory
Page 19 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

is present, the content will be copied by the assignment operator. The write index
and the filling level will be incremented, considering the special handling required for
position 0. The boolean return value reflects the success of the operation.
 The read operation reads a value from the current read index position. The read
index will be incremented, again considering the special handling required for position 0.
The filling level will be decremented. The boolean return value reflects the
success of the operation.
 The destructor deletes the memory of the elements as well as the dynamic array
holding the pointers.

4.1 Implementation (15)


Modify / complete the non template code to a template class.

//Templatisation: 5 points
//Destructor: 2 points
//Write: 8 points
Template <class T>
class CRingBuffer
{
private:
T** m_pBuffer; //Pointer to the dynamic array representing the buffer
unsigned int m_size; //Size of the ringbuffer
unsigned int m_filled; //Number of elements in the buffer
unsigned int m_idxRead; //Read index
unsigned int m_idxWrite; //Write Index

public:
CRingBuffer(unsigned int size);
~CRingBuffer();

bool write(T element);


bool read (T& element);

void print();

};

Template <class T>


CRingBuffer<T>::CRingBuffer(unsigned int size)
{
m_size = size;

m_filled = 0;
m_idxRead = 0;
m_idxWrite = 0;

m_pBuffer = new T*[m_size];

for (unsigned int i = 0; i < m_size;i++)


Page 20 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

{
m_pBuffer[i] = (T*)0; //cast optional
}

Template <class T>


CRingBuffer<T>::~CRingBuffer()
{
// Delete the dynamic array of the ringbuffer as well as the
// allocated memory for the data elements

for (unsigned int i = 0; i < m_size;i++)


{
if (m_pBuffer[i] != 0) delete m_pBuffer[i];
}

delete[] m_pBuffer;
}

Template <class T>


bool CRingBuffer<T>::write(T element)
{

if (m_filled < m_size) //1


{
if (m_pBuffer[m_idxWrite] == 0) //1
{
m_pBuffer[m_idxWrite] = new T(element); //Copy constructor //2
}
else
{
*m_pBuffer[m_idxWrite] = element; //Assignment operator //1
}
m_idxWrite ++; //3 for the complete rest
m_idxWrite %= m_size;
m_filled++;
return true;
}
else
{
return false;
}
}

Template <class T>


bool CRingBuffer<T>::read(T& element)
{
// Return an element from the ringbuffer, if data is available

if (m_filled > 0)
{
element = *m_pBuffer[m_idxRead++];

Page 21 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

m_idxRead %= m_size;
m_filled--;
return true;
}
else
{
return false;
}
}

Template <class T>


void CRingBuffer<T>::print()
{
for (unsigned int i = 0; i < m_filled; i++)
{
unsigned int pos = (m_idxRead + i) % m_size;
cout << "Element at position " << pos << " = " << *m_pBuffer[pos] << endl;
}
}

4.2 Overloaded functions / operations (5)


Add comments to every line in the code above, which requires a dedicated constructor / destructor
/ method / overloaded operator …. of the template parameter class. Name the required method in
the comment.
 Copy Constructor
 Assignment (twice)
 << operator
 Destruktor

Page 22 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

5 Cheat sheet
std::<container>::insert
single element
iterator insert (iterator position, const value_type& val);
(1)

fill (2) void insert (iterator position, size_type n, const


value_type& val);
template <class InputIterator>
range (3) void insert (iterator position, InputIterator first,
InputIterator last);
Insert elements
The container is extended by inserting new elements before the element at the specified position.

This effectively increases the container size by the amount of elements inserted.

The arguments determine how many elements are inserted and to which values they are initialized:

Parameters
position
Position in the container where the new elements are inserted.
iterator is a member type, defined as a bidirectional iterator type that points to elements.
val
Value to be copied (or moved) to the inserted elements.
Member type value_type is the type of the elements in the container, defined in list as an
alias of its first template parameter (T).
n
Number of elements to insert. Each element is initialized to a copy of val.
Member type size_type is an unsigned integral type.
first, last
Iterators specifying a range of elements. Copies of the elements in the range
[first,last) are inserted at position (in the same order).
Notice that the range includes all the elements between first and last, including the element
pointed by first but not the one pointed by last.
The function template argument InputIterator shall be an input iterator type that points
to elements of a type from which value_type objects can be constructed.
il
An initializer_list object. Copies of these elements are inserted at position (in the same
order).

Page 23 / 24
System Design (1010 / 1039 MSE) Prof. P. Fromm / Prof. M. Lipp

These objects are automatically constructed from initializer list declarators.


Member type value_type is the type of the elements in the container, defined in list as an
alias of its first template parameter (T).

Return value
An iterator that points to the first of the newly inserted elements.

Member type iterator is a bidirectional iterator type that points to elements.

The storage for the new elements is allocated using the container's allocator, which may throw
exceptions on failure (for the default allocator, bad_alloc is thrown if the allocation request does
not succeed).

Page 24 / 24

Das könnte Ihnen auch gefallen