Object Oriented Software Design II



Similar documents
Object Oriented Software Design II

Object Oriented Software Design II

C++FA 5.1 PRACTICE MID-TERM EXAM

Storage Classes CS 110B - Rule Storage Classes Page 18-1 \handouts\storclas

PART-A Questions. 2. How does an enumerated statement differ from a typedef statement?

Introduction to C++ Introduction to C++ Week 7 Dr Alex Martin 2013 Slide 1

C++ Programming Language

CS193D Handout 06 Winter 2004 January 26, 2004 Copy Constructor and operator=

KITES TECHNOLOGY COURSE MODULE (C, C++, DS)

Polymorphism. Problems with switch statement. Solution - use virtual functions (polymorphism) Polymorphism

Top 10 Bug-Killing Coding Standard Rules

CORBA Programming with TAOX11. The C++11 CORBA Implementation

C++ Support for Abstract Data Types

CpSc212 Goddard Notes Chapter 6. Yet More on Classes. We discuss the problems of comparing, copying, passing, outputting, and destructing

Design Patterns in C++

Embedded Programming in C/C++: Lesson-1: Programming Elements and Programming in C

Binary storage of graphs and related data

Course Name: ADVANCE COURSE IN SOFTWARE DEVELOPMENT (Specialization:.Net Technologies)

C++ INTERVIEW QUESTIONS

Informatica e Sistemi in Tempo Reale

Ch 7-1. Object-Oriented Programming and Classes

Multichoice Quetions 1. Atributes a. are listed in the second part of the class box b. its time is preceded by a colon. c. its default value is

IS0020 Program Design and Software Tools Midterm, Feb 24, Instruction

C++ Crash Kurs. C++ Object-Oriented Programming

Note: Syntactically, a ; is needed at the end of a struct definition.

13 Classes & Objects with Constructors/Destructors

Reading and Writing PCD Files The PCD File Format The Grabber Interface Writing a Custom Grabber PCL :: I/O. Suat Gedikli, Nico Blodow

C++FA 3.1 OPTIMIZING C++

CS107L Handout 02 Autumn 2007 October 5, 2007 Copy Constructor and operator=

The C Programming Language course syllabus associate level

Short Notes on Dynamic Memory Allocation, Pointer and Data Structure

C++ DATA STRUCTURES. Defining a Structure: Accessing Structure Members:

Copyright 2001, Bill Trudell. Permission is granted to copy for the PLoP 2001 conference. All other rights reserved.

Compiler Construction

N3458: Simple Database Integration in C++11

Parameter Passing. Standard mechanisms. Call by value-result Call by name, result

ELEG3924 Microprocessor Ch.7 Programming In C

Sources: On the Web: Slides will be available on:

Semantic Analysis: Types and Type Checking

1. Polymorphism in C++...2

Basics of C++ and object orientation in OpenFOAM

Comp151. Definitions & Declarations

How Safe does my Code Need to be? Shawn A. Prestridge, Senior Field Applications Engineer

Answers to Review Questions Chapter 7

Practical Programming Methodology. Michael Buro. Class Inheritance (CMPUT-201)

An Incomplete C++ Primer. University of Wyoming MA 5310

Variable Base Interface

Keil C51 Cross Compiler

C++ Overloading, Constructors, Assignment operator

sqlpp11 - An SQL Library Worthy of Modern C++

An API for Reading the MySQL Binary Log

Lecture 3. Arrays. Name of array. c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[8] c[9] c[10] c[11] Position number of the element within array c

Chapter 13 Storage classes

1.1.3 Syntax The syntax for creating a derived class is very simple. (You will wish everything else about it were so simple though.

public static void main(string[] args) { System.out.println("hello, world"); } }

Boolean Expressions, Conditions, Loops, and Enumerations. Precedence Rules (from highest to lowest priority)

Lecture 22: C Programming 4 Embedded Systems

Introduction to Programming Block Tutorial C/C++

vector vec double # in # cl in ude <s ude tdexcept> tdexcept> // std::ou std t_of ::ou _range t_of class class V Vector { ector {

El Dorado Union High School District Educational Services

C++ Object Persistence with ODB

Data Structures using OOP C++ Lecture 1

How To Port A Program To Dynamic C (C) (C-Based) (Program) (For A Non Portable Program) (Un Portable) (Permanent) (Non Portable) C-Based (Programs) (Powerpoint)

The programming language C. sws1 1

Subject Name: Object Oriented Programming in C++ Subject Code:

For the next three questions, consider the class declaration: Member function implementations put inline to save space.

Operator Overloading. Lecture 8. Operator Overloading. Running Example: Complex Numbers. Syntax. What can be overloaded. Syntax -- First Example

5 CLASSES CHAPTER. 5.1 Object-Oriented and Procedural Programming. 5.2 Classes and Objects 5.3 Sample Application: A Clock Class

Adding Alignment Support to the C++ Programming Language / Wording

Konzepte objektorientierter Programmierung

1 Abstract Data Types Information Hiding

Java from a C perspective. Plan


MPLAB Harmony System Service Libraries Help

CUDA Programming. Week 4. Shared memory and register

Advanced Data Structures

Implementation Aspects of OO-Languages

6.S096 Lecture 1 Introduction to C

Compiling Object Oriented Languages. What is an Object-Oriented Programming Language? Implementation: Dynamic Binding

AP Computer Science Java Subset

C Programming Review & Productivity Tools

CS107L Handout 04 Autumn 2007 October 19, 2007 Custom STL-Like Containers and Iterators

Development Techniques for Native/Hybrid Tizen Apps. Presented by Kirill Kruchinkin

Real-Time Multitasking in Arduino. Pasquale Buonocunto, Alessandro Biondi, Pietro Lorefice

Applying Clang Static Analyzer to Linux Kernel

6.088 Intro to C/C++ Day 4: Object-oriented programming in C++ Eunsuk Kang and Jean Yang

Objectif. Participant. Prérequis. Remarque. Programme. C# 3.0 Programming in the.net Framework. 1. Introduction to the.

More C++ Concepts. Operator overloading Friend Function This Operator Inline Function

6. Control Structures

An Overview of Java. overview-1

RTI Monitoring Library Getting Started Guide

C++ Outline. cout << "Enter two integers: "; int x, y; cin >> x >> y; cout << "The sum is: " << x + y << \n ;

Introduction to Object Oriented Programming (OOP)

MPLAB TM C30 Managed PSV Pointers. Beta support included with MPLAB C30 V3.00

Transcription:

Object Oriented Software Design II Real Application Design Christian Nastasi http://retis.sssup.it/~lipari http://retis.sssup.it/~chris/cpp Scuola Superiore Sant Anna Pisa April 25, 2012 C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 1 / 44 Outline 1 Previously... 2 Non-local variable initialization 3 Application to Factories 4 Initialization Order Fiasco 5 Construct On First Use idiom 6 Back to the duck-lab C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 2 / 44

Data AcQuisition System A basic DAQ system duck-lab: an open-source DAQ framework Project (temporary) home page: http://retis.sssup.it/~chris/duck-lab Mercurial revision control: https://rtn.sssup.it/hg/duck-lab (hg clone https://rtn.sssup.it/hg/duck-lab) C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 4 / 44 duck-lab architecture...010010110011001... I/O Library Streamer... 0xFF 0xAF 0x47... Formatter Core Library Data Vector D1 D2 D3... Dn Storage Library Storage Vector S1 S2 S3... Sm XML Configuration We have defined a hierarchy for Data We have defined the interaction with the Formatter, implemented by the FormatHandler class C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 5 / 44

duck-lab architecture Metadata #type: std::string #type_size: unsigned long #length: unsigned long +get_type(): std::string +get_type_size(): unsigned long +get_len(): unsigned long +get_tot_size(): unsigned long +~Metadata() #name: std::string Data +get_name(): std::string +format_data(buff:const unit8_t*,len:unsigned long): unsigned long T: DataTemplate +actual_data: T[] +DataTemplate() +~DataTemplate() data_vector <<bind>> <int8_t> <<bind>> <uint16_t> <<bind>> <float> +data_vector: Data[] FormatHandler DataInt8 DataUInt16 DataFloat32 -FormatHandler() +~FormatHandler() -format(in rawdata:uint8_t*,in len:unsigned long) C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 6 / 44 The FormatHandler class We have done Data creation/destruction We have done Data formatting class FormatHandler FormatHandler(); ~FormatHandler(); void format(const uint8_t* rawdata, unsigned long len); std::vector<data*> data_vector; ; Factory Method Pattern with string-based look-up table (std::map) (almost good) Polymorphic destruction (good!) Polymorphic formatting with delegation to the Data classes (good!) So, given the following configuration (XML) <message_description> <data data_type="uint16" data_name="data_name_1" data_len="2"/> <data data_type="float32" data_name="data_name_2" data_len="1"/> <data data_type="int8" data_name="data_name_3" data_len="4"/> </message_description> C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 7 / 44

FormatHandler ctor and dtor DataExample5-to-exercise-solution/FormatHandler.cc FormatHandler::FormatHandler() // We create the data vector according to XML config vector<xmldataelement> config = parse_xml_data(); vector<xmldataelement>::const_iterator it; for (it = config.begin(); it!= config.end(); ++it) Data *d = DataFactory::create(it->type, it->name, it->len); if (!d) cout << "Unable to create data type = " << it->type << "! Skipping" << endl; continue; data_vector.push_back(d); DataExample5-to-exercise-solution/FormatHandler.cc FormatHandler::~FormatHandler() // We have to destroy the data vector properly vector<data*>::iterator it; for (it = data_vector.begin(); it!= data_vector.end(); ++it) delete *it; C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 8 / 44 DataFactory Has anybody finished, if started, doing last exercise? DataExample5-to-exercise-solution/DataFactory.h class DataFactory typedef Data* (*creator_type_t)(const std::string&, unsigned long); static Data* create(const std::string& id, const std::string& name, unsigned long len); static std::map<std::string, creator_type_t> lookup_table; ; DataExample5-to-exercise-solution/DataFactory.cc std::map<string, DataFactory::creator_type_t> DataFactory::lookup_table; Data* DataFactory::create(const string& id, const string& n, unsigned long len) if (lookup_table.empty()) lookup_table["int8"] = DataInt8::create; lookup_table["uint16"] = DataUInt16::create; lookup_table["float32"] = DataFloat32::create; map<string, creator_type_t>::iterator elem = lookup_table.find(id); if (elem == lookup_table.end()) cout << "Fatory Creation Error: Creator not registered" " for ID=" << id << endl; return NULL; return elem->second(n, len); C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 9 / 44

Definitions Static storage duration Variables shall last for the entire duration of the program Variables with constructor/destructor having side effects cannot be eliminated Non-local variables Typically known as global variables Either with static storage duration... or thread storage duration (defined in C++11) Non-local variables with static storage duration are initialized as a consequence of program initiation. [C++11 standard: n3242, sec 3.6.2] C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 11 / 44 Variables with static storage duration Three possible cases: Non-local variables int var1; static float var2; int main(void) return 0; Static as linkage rule Local variables void f(void) static int var = 123; //... Declaration of static durarion Static class data member (treated as non-local variable) class Test //... static int var; ; int Test::var; Declare static class member Necessary to define (allocate) data member Notice the different usages of static C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 12 / 44

Initialization Type Two possible initializations static initialization zero initialization int var; int* ptr; int array[3]; float real; int main(void) return 0; constant initialization int var = 123; int* ptr = &var1; int array[3] = 1, 2, 3; int main(void) return 0; dynamic initialization: all other initializations inline int f() return 123; int var = f(); float real = 3.14; // Dynamic Initilization! int main(void) return 0; C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 13 / 44 Initialization: Static vs Dynamic Considering non-local variable with static storage duration Static initialization Initialization value computed at compile time All static initializations occur before any dynamic initialization Dynamic initialization Note: Initialization value computed at runtime Under certain circumstances static initialization might be used in place of dynamic one Initialization might occur before first statement of main, otherwise... it shall occur before the first odr-use of any function or variable defined in the same translation unit as the variable to be initialized. [C++11 standard: n3242, sec 3.6.2, par 4] A non-local variable with static storage duration having initialization with side-effects must be initialized even if it is not odr-used [C++11 standard: n3242, sec 3.6.2, note 34] Variables might be static- (zero-) initialized first and dynamic-initialized later. User-defined types variable (classes) are subject to static and dynamic initialization too. C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 14 / 44

User-defined type: static initialization if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits struct Simple int var; int* ptr; char str[10]; ; Simple s; int main(void) cout << "Simple has: " << s.var << " " << s.ptr << " " << s.str << " " << endl; return 0; [C++11 standard: n3242, sec 8.5, par 5] Simple has: 0 0 C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 15 / 44 User-defined type: dynamic initialization When zero-initializtion constuction is not sufficient... struct Simple int var; int* ptr; char str[10]; Simple() : var(123), ptr(&var) strcpy(str, "Hello"); ; Simple s; User-provided constructor Requesting a run-time call to the user-provided constructor int main(void) cout << "Simple has: " << s.var << " " << s.ptr << " " << s.str << " " << endl; return 0; Simple has: 123 0x6013a0 Hello C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 16 / 44

And now? The question is: why do we care about all this stuff? It turns out that non-local variable initialization can be exploited to execute code at start-up. Suppose to have: Dynamic initialization might occur before first statement of main, otherwise... it shall occur before the first odr-use of any function or variable defined in the same translation unit as the variable to be initialized. A non-local variable with static storage duration having initialization with side-effects must be initialized even if it is not odr-used a non-local variable of user-defined type (class) which a user-provided constructor which has side-effects (produces changes in the execution environment) C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 17 / 44 Example struct MyClass MyClass() cout << "Make world..." << endl; //... //... ; MyClass c; int main(void) cout << "Hello world!" << endl; return 0; Make world... Hello world! C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 18 / 44

The Disney s cartoons problem The user wants to animate cartoons The user does not care about their creation process C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 20 / 44 C++ implementation FactoryExample4.h class DisneyProduct virtual ~DisneyProduct() ; inline std::string get_name(void) const return name; ; protected: DisneyProduct(const std::string& n) : name(n) ; DisneyProduct(const DisneyProduct&); DisneyProduct &operator=(const DisneyProduct&); std::string name; ; FactoryExample4.h class Goofy : public DisneyProduct Goofy() : DisneyProduct("goofy") ; static DisneyProduct* create(void) return new Goofy(); ; friend class DisneyFactory; ; class Pluto : public DisneyProduct Pluto() : DisneyProduct("pluto") ; static DisneyProduct* create(void) return new Pluto(); ; friend class DisneyFactory; ; C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 21 / 44

C++ implementation FactoryExample4.h class DisneyUser DisneyUser(); ~DisneyUser(); void animate(void); std::vector<disneyproduct*> toons; ; C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 22 / 44 C++ implementation FactoryExample4.cc DisneyUser::DisneyUser() const char* config[] = "goofy", "pluto", "pluto", "invalid_id"; for (size_t i = 0; i < 4; i++) DisneyProduct *p = DisneyFactory::create(config[i]); if (p) toons.push_back(p); DisneyUser::~DisneyUser() vector<disneyproduct*>::iterator it; for (it = toons.begin(); it!= toons.end(); ++it) delete *it; void DisneyUser::animate(void) vector<disneyproduct*>::const_iterator it; for (it = toons.begin(); it!= toons.end(); ++it) cout << "Hullo, my name is " << (*it)->get_name() << endl; C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 23 / 44

C++ implementation FactoryExample4.h class DisneyFactory static DisneyProduct* create(const std::string& id); typedef DisneyProduct* (*creator_type_t)(void); static std::map<std::string, creator_type_t> lookup_table; ; FactoryExample4.cc map<std::string, DisneyFactory::creator_type_t> DisneyFactory::lookup_table; DisneyProduct* DisneyFactory::create(const string& id) if (lookup_table.empty()) lookup_table["goofy"] = Goofy::create; lookup_table["pluto"] = Pluto::create; if (lookup_table.find(id) == lookup_table.end()) return NULL; return lookup_table[id](); C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 24 / 44 Consideration What about extensibility? Adding new DisneyProduct requires the following modifications: 1 definition of the new DisneyProduct (e.g. DonalDuck) 2 adding a new entry in the look-up table... if (lookup_table.empty()) lookup_table["goofy"] = Goofy::create; lookup_table["pluto"] = Pluto::create; lookup_table["donal duck"] = DonalDuck::create;... in the DisneyFactory class implementation Using non-local variable initialization we can avoid step 2! C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 25 / 44

Factory with automatic registration The DisneyFactory shall contain the logic to register the creation method in the look-up table. This registration is performed at run-time and at start-up But where do we write this code? In the constructor, of course! FactoryExample5.h class DisneyFactory typedef DisneyProduct* (*creator_type_t)(void); DisneyFactory(const std::string& id, creator_type_t func); static DisneyProduct* create(const std::string& id); static std::map<std::string, creator_type_t> lookup_table; ; C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 26 / 44 Factory with automatic registration FactoryExample5.cc map<std::string, DisneyFactory::creator_type_t> DisneyFactory::lookup_table; DisneyFactory::DisneyFactory(const string& id, creator_type_t func) cout << "Factory: registrating creator for id=" << id << endl; if (lookup_table.find(id)!= lookup_table.end()) cout << "Error: ID already in look-up table" << endl; return; lookup_table[id] = func; DisneyProduct* DisneyFactory::create(const string& id) if (lookup_table.find(id) == lookup_table.end()) return NULL; return lookup_table[id](); C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 27 / 44

Factory with automatic registration Each concrete DisneyProduct class shall automatically register itself... just defining a non-local variable with static storage duration of type DisneyFactory. class Goofy : public DisneyProduct static DisneyProduct* create(void) return new Goofy(); ; Goofy() : DisneyProduct("goofy") ; ; // In the implementation file... DisneyFactory register_goofy("goofy", Goofy::create); The full example is:./examples/10.real-application_moreoncreation-examples/factorye C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 28 / 44 Initialization order Variables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit. [C++11 standard: n3242, sec 3.6.2, par 2] In other words: global variables are initialized following the order of appearance in the source file; but the initialization order is not guaranteed between variables of different source files! C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 30 / 44

Initialization order fiasco Goofy.cc class Goofy : public DisneyProduct static DisneyProduct* create(void) return new Goofy(); ; Goofy() : DisneyProduct("goofy") ; ; DisneyFactory reg("goofy", Goofy::create); DisneyFactory.cc map<std::string, DisneyFactory::creator_type_t> DisneyFactory::lookup_table; DisneyFactory::DisneyFactory(const string& id, creator_type_t func) if (lookup_table.find(id)!= lookup_table.end()) cout << "Error: already in look-up table" << endl; return; lookup_table[id] = func; C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 31 / 44 How to prevent the fiasco The problem of previous example: If DisneyFactory::lookup_table is not initialized before the non-local object reg... then the call to the constructor (registration mechanism) DisneyFactory::DisneyFactory(...) fails! Solution for the previous example? Make DisneyFactory::lookup_table a pointer to map rather than a map object. As a pointer it shall be zero-initialized (static initialization) before any dynamic initialization. Delay the creation of the actual map until it is necessary: when it is used by DisneyFactory::DisneyFactory(...). C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 32 / 44

How to prevent the fiasco DisneyFactory.cc map<std::string, DisneyFactory::creator_type_t>* DisneyFactory::lookup_table; DisneyFactory::DisneyFactory(const string& id, creator_type_t func) if (!lookup_table) lookup_table = new map<std::string, creator_type_t>(); if (lookup_table->find(id)!= lookup_table->end()) cout << "Error: already in look-up table" << endl; return; (*lookup_table)[id] = func; The generalization of this approach is known as Construct On First Use idiom. C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 33 / 44 Construct On First Use Idiom Objective: Ensure that an object is initialized before its first use. Specifically, ensure that a non-local static object is initialized before its first use. Solution: Encapsulate the creation of the critical object in a function. Basically the object is now a local variable with static storage duration which is initialized only when the function is called! Also known as lazy initialization/evaluation (not at startup) MyClass& getmyobj() static MyClass* p = new MyClass; return *p; C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 35 / 44

Example [http://www.parashift.com/c++-faq-lite/ctors.html] x.cc #include "Fred.h" Fred x; y.cc #include "Barney.h" Barney y; Barney.cc #include "Barney.h" Barney::Barney() //... x.gobowling(); //... x.cc #include "Fred.h" Barney.cc #include "Barney.h" Fred& x() static Fred* ans = new Fred(); return *ans; Barney::Barney() //... x().gobowling(); //... C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 36 / 44 Alternative implementation... Dynamic allocation #include "Fred.h" Fred& x() static Fred* ans = new Fred(); return *ans; Local static #include "Fred.h" Fred& x() static Fred ans; return ans; The destructor for ans is not called, ever! Not good if destructor is non-trivial. The destructor for ans is called on program termination. Might generate destruction order fiasco! C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 37 / 44

DataFactory with automatic registration The DataFactory class shall have a constructor to register the creator functions. The creator functions shall be defined by each concrete data-class: DataInt8 DataUInt16 DataFloat32... A utility macro might be used to generate the code for the creator function given a public constructor. The full example is:./examples/10.real-application_moreoncreation-examples/dataexam C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 39 / 44 Consideration What about extensibility? Adding new Data requires the following modifications: 1 definition of the new concrete Data (e.g. DataFloat64, DataImageRGB) 2 adding the automatic registration (one line if using the macro) Notice: Both changes are to the implementation file of the new class! No more changes are required to other files! C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 40 / 44

Different creation parameters We have now an extensible solution with respect to new Data. However, the creation function accepts always the same parameters! DataExample6/DataFactory.h class DataFactory typedef Data* (*creator_type_t)(const std::string&, unsigned long); DataFactory(const std::string& id, creator_type_t func); Fine for basic data types... DataExample6/DataInt8.h class DataInt8 : public DataTemplate<int8_t> DataInt8(const std::string& name, unsigned long len); ; C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 41 / 44 Different creation parameters Consider the DataImageRGB example... a new concrete data to manage images in RGB format class DataImageRGB : public Data DataImageRGB(const std::string& name, unsigned long len, unsigned width, unsigned height) : Data("ImageRGB", name, width * height * 3, len) // Allocate internal representation // for RGB image with resolution width x height //... ; ~DataImageRGB() // Deallocations... ; ; unsigned long format_data(const uint8_t* buff, unsigned long len) // Formatting... ; //... The constructor requires two more params: width and height C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 42 / 44

Different creation parameters The parameters width and height should be coded in the XML configuration file <message_description> <data data_type="imagergb" data_name="data_name_3" data_len="1"> <RGB_config width="160" height="120"> </data> </message_description> Problem: is the configuration logic: DataExample5-to-exercise-solution/FormatHandler.cc FormatHandler::FormatHandler() // We create the data vector according to XML config vector<xmldataelement> config = parse_xml_data(); vector<xmldataelement>::const_iterator it; for (it = config.begin(); it!= config.end(); ++it) Data *d = DataFactory::create(it->type, it->name, it->len); if (!d) cout << "Unable to create data type = " << it->type << "! Skipping" << endl; continue; data_vector.push_back(d); Solution: Delegate the XML parsing to the Factory... and to enforce extensibility, eventually delegate to the concrete data class! C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 43 / 44 duck-lab approach The solution adopted in the duck-lab uses a two-way factory : A Parser class is defined to access the XML A DataConfig class is defined to store the config information retrieved through the Parser The Data class is created from the DataConfig Motivation: separating the concrete Data class from its configuration. Parser DataConfig Data XML Configuration Factory 1 Factory 2 C. Nastasi (Scuola Superiore Sant Anna) C++ Intro April 25, 2012 44 / 44