Implementing An OOD
description
Transcript of Implementing An OOD
![Page 1: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/1.jpg)
Implementing An OOD
(Chapters 3, 4)
![Page 2: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/2.jpg)
Two Basic Steps
Convert the class diagram into C++ class declarations (header file)
Convert the pseudocode into C++ methods (code file)
Separation of files facilitates separate compilation, covered later.
![Page 3: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/3.jpg)
Elements of Good C++ Code
1) Readability2) Consistent naming conventions3) Code format4) Comments5) Language conventions6) Coding style
![Page 4: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/4.jpg)
Example: flush Program Problem Statement:
write a program that represents a deck of cards, simulates the dealing of poker hands, and estimates the probability of dealing a flush, that is, a
hand with at least five cards of the same suit.
![Page 5: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/5.jpg)
Sample Script8% flush
Enter no. of cards in each hand (5-9): 7
Enter no. of hands to deal: 1000DECK:8D 1C 8H 5S 7C 2D 1H 10D 2S 6D 7S 2H 11H 10S 13C 11D 3C 3D 3H 9H 10C 2C 10H 7D 6H 12S 6C 3S 9D 1D 11S 5H 13D 7H 9S 4C 6S 8S 12D 5D 1S 9C 13H 5C 13S 4D 12C 8C 4S 11C 4H 12H
In 1000 7-card hands there were 35 flushes9%
![Page 6: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/6.jpg)
Chosen Object Classes
Simulation Deck Card Pip Suit
![Page 7: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/7.jpg)
Simulation Class Aspects
contains a Deck object manages the simulation of the dealing of multiple
hands determines a frequency distribution of flushes methods should be provided for:
creating a Simulation object getting simulation parameters from user managing the simulation, including memory reporting results
![Page 8: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/8.jpg)
Simulation Class Diagram
![Page 9: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/9.jpg)
Simulation Class Implementation in C++
class SimulationInfo {private: Deck the_deck; // The current deck CardArray one_hand; // The current hand IntArray suit_counts; // Suit counts in current
// hand Integer flush_count; // Total flush count Integer num_hands; // Total number of hands // to deal Integer hand_size; // Hand size (5-9 cards) Integer hands_per_deck;// Number of hands that // can be dealt per deck . . .
![Page 10: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/10.jpg)
Simulation Class (cont'd) . . .public: SimulationInfo(); // Creates a new deck,
// space for one hand, // and suit count array. void free(); // Returns memory created by
// constructor. void getdata(); // Prompts for hand size and
// number of hands. void simulate(); // Performs the dealing simulation. void report(); // Reports results.private: void loopThroughHands(); // Implements outer loop of
// simulation. void dealAndCheckHand(); // Deals and checks one hand for
// a flush. void initSuitCounts(); // Initializes suit counts to zero. void incSuitCount(); // Increments suit count for each
// card in hand. void checkFlush(); // Checks suit counts for values
// >= 5 and increments flush // count if appropriate.
};
![Page 11: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/11.jpg)
Elements of a Good C++ Class Definition
Comments describe fields and methods when appropriate
Blank lines promote readability Public methods precede private methods Method argument names are provided Data names are private (or protected) Methods not called externally are private Class constructor and destructor are explicitly
defined (even though C++ can do it implicitly)
![Page 12: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/12.jpg)
Relationship Between Types Simulation and SimulationInfo
SimulationInfo is a C++ class type Simulation is a C++ pointer type Nearly every reference to a simulation will be via
the pointer type One main exception: class construction Why? Because C++ forces us to distinguish
between pointer and pointee We must deal with pointers, and we must give
back the memory to which they point
![Page 13: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/13.jpg)
Pointers and ObjectsUnlike "pure" OOP languages like Java, Smalltalk, and Eiffel, C++ distinguishes between objects and pointers to them.
Thus there are two different syntaxes for method invocation:
obj.method if obj is a nonpointerobjptr->method if objptr is a pointer
To avoid confusion and allow for dynamic object creation, a consistent style of class definition is used.
![Page 14: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/14.jpg)
Pointers and Objects (cont'd)Use the pointer type Simulation when declaring:
- variables- parameters- data fields
Use the class type SimulationInfo to create anobject with new.
Once pointers exist, use the "->" form of referencefor both method and data access.
Finally, explicitly free all objects with delete.
![Page 15: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/15.jpg)
Pointers and Objects (cont'd) In general the actual class name, like SimulationInfo, is only used with the new operator. Exceptions:When referencing or calling a static method
Example: StateInfo::blankUpWhen small pieces of structured data (like a graphics
point) are copied over and over. These should be coded as structs instead of classes.
When a class is meant to act as a primitive element of the language (like a complex or rational number)
![Page 16: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/16.jpg)
Using typedef for Clarity
We want to limit use of the C/C++ pointer token (*) for both clarity and similarity to Java
We use typedef for this purpose:
typedef <existing type> <new type identifier>;
typedef class SimulationInfo * Simulation;typedef class DeckInfo * Deck;typedef class CardInfo * Card;typedef class PipInfo * Pip;typedef class SuitInfo * Suit;
If the typedef appears before the class definition,the class modifier is required as a forward reference.
![Page 17: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/17.jpg)
flush Main Program
main() { Simulation s = new SimulationInfo; s->getdata(); s->simulate(); s->report(); s->free();}
![Page 18: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/18.jpg)
Virtues of this Approach Pointer references are much more efficient than
class references as: class instance variables (construction time) method parameters (call by value)
Enforces the discipline of dynamically creating all objects from the heap, and returning objects to the system when no longer needed.
Facilitates syntax so that all object data or method references are made using obj->data or obj->method
![Page 19: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/19.jpg)
Naming Conventions in C++Identifier Type ExamplesType name Integer
SimulationState
Method name solvesimulatecheckFlush
Field name (data) flush_countproblemproblem_
Local variable icount
Constant NUM_TILES
![Page 20: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/20.jpg)
Standard Types
The basic type names of C++ do not conform to thenaming conventions. So use typedef to solve this:
typedef int Integer;typedef int * IntArray;typedef char Boolean;typedef char Character;typedef double Float;typedef char * String;typedef String * StringArray;typedef Card * CardArray;
![Page 21: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/21.jpg)
File Structure
Class and method definitions should be system- atically broken up into separate files, so that:
Readability is enhanced Changes are localized Program pieces can be separately compiled
C++ systems are composed of two types of files: Header files: contain declarations only (.H type) Code files (.cc or .C type)
![Page 22: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/22.jpg)
Header FilesAll header files have a common structure. Example:
// ****************************************// file: SolverInfo.H// author: T. Colburn// purpose: General problem solver header file// modified: 09/11/02// ****************************************
#ifndef SOLVERINFO_USED#define SOLVERINFO_USED
#include "ProblemInfo.H"
class SolverInfo { . . .};
#endif
![Page 23: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/23.jpg)
Header File Structure
A block comment shows file name, description, author, and any version or modification information
The #ifndef-#define-#endif is a "guard" against the file being included more than once (see next slide)
Toward the top should be parameters (consts), typedefs, and enumerations (in the example, these are included from ProblemInfo.H)
After that, the declarations of the actual classes
![Page 24: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/24.jpg)
Multiply Defined Symbols
#include "Bar.H"#include "Baz.H". . .
#include "Bar.H". . .
<symbols in here aremultiply defined>
Foo.H
Bar.H Baz.H
![Page 25: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/25.jpg)
Levels of Header Files Unless the program is fairly trivial, there should be
a header file for each class: SolverInfo.H ProblemInfo.H StateInfo.H ActionInfo.H ActionListInfo.H
In your lab exercise, you can have one header file for all classes:
Flush.H
![Page 26: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/26.jpg)
Code Files Code files implement the methods declared in
header files. There should be one code file for each class, e.g. SolverInfo.cc, ProblemInfo.cc. etc.
Each code file should have a block comment at the top, and #include its corresponding header file.
Code files should have no local definitions, like enumerations or non-class support functions (should be private static methods instead).
Method bodies should be limited in size to what can be displayed on one screen.
![Page 27: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/27.jpg)
Code File Example// *****************************************// file: SolverInfo.cc// author: T. Colburn// purpose: Implements SolverInfo class methods// modified: 09/11/02// *****************************************
#include <iostream.h>#include "SolverInfo.H"
SolverInfo::SolverInfo(Problem p) { . . .}
void SolverInfo::solve() { . . .}
String SolverInfo::promptActionName() { . . .}
![Page 28: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/28.jpg)
Memory Management
SimulationInfo::SimulationInfo() { the_deck = new DeckInfo(); one_hand = new Card[9]; suit_counts = new Integer[4];}
Note that memory is allocated dynamically, that is,the DeckInfo object and supporting arrays areallocated at run time.
Consider the SimulationInfo Constructor:
![Page 29: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/29.jpg)
Memory Management Problems Array out of bounds Dangling pointer references Memory leaks
Memory management is the biggest problem when using C++.
Solution: Plan memory management as part of the design.
![Page 30: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/30.jpg)
Array Out Of Bounds
Since arrays are represented simply as pointers to memory, C++ does not check array bounds
Any array operation must have explicit bounds checks put in by programmer
Whenever an array is passed, its size should also be passed
![Page 31: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/31.jpg)
Dangling Pointer Referencesptr = new ClassInfo(. . .);
.
.
.
delete ptr;...
<code that later uses ptr again>
ClassInfoObjectptrptr
ptrptr Who knows whatptr is pointing tonow.
"Weird and wondrous" behavior ensues
Partial Solution: follow the delete with ptr = NULL;
![Page 32: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/32.jpg)
Memory LeaksSuppose the following is in a loop:
ptr = new ClassInfo(. . .);...
<loop ends without any delete>
ClassInfoObject1
ClassInfoObject2
ClassInfoObject3
ClassInfoObject4
ClassInfoObject5
ptr
.
.
.
![Page 33: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/33.jpg)
Preventing Memory Leaks
Use automatic garbage collection (not currently available in C++)
Do reference counting. Each object keeps a count of its users. When the count reaches zero, the object is deleted.
Assign an owner to each object whenever possible, and have the owner be responsible for freeing memory (our approach).
![Page 34: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/34.jpg)
Memory Management in the flush Program
SimulationInfoObject
Array of 9 Card Pointers
Deck Pointer,DeckInfo Object Array of 4 Integers
creates creates creates
![Page 35: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/35.jpg)
DeckInfo Class
class DeckInfo {private: CardArray cd_array; // 52-element array to hold cardspublic: DeckInfo(); // Create the deck by allocating // cd_array and creating a new
// card for each element. void free(); // Return memory created by
// constructor. void shuffle(); // Shuffle deck by randomly
// swapping elements. void deal(Integer, Integer, // Deal cards into a hand.
CardArray); void print(); // Print all cards in the deck.};
![Page 36: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/36.jpg)
DeckInfo ConstructorDeckInfo::DeckInfo() { cd_array = new Card[52]; // Create new card array for (Integer i = 0; i < 52 ; i++) // Fill array cd_array[i] = new CardInfo(i); // with new cards}
DeckInfo Object
Array of 52 CardPointers,52 CardInfoObjects
creates
![Page 37: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/37.jpg)
CardInfo Classclass CardInfo {private: Integer deck_position; // This card's deck_position Suit the_suit; // This card's suit Pip the_pip; // This card's pippublic: CardInfo(Integer n); // Create a new card with suit and // pip depending on deck_position.
void free(); // Return space for this card and // its suit and pip objects.
Pip getPip(); // Retrieve pip object for this // card.
SuitInfo::type getSuitType(); // Retrieve suit type for this // card.
void print(); // Print this card by printing pip // value and suit.};
![Page 38: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/38.jpg)
CardInfo Constructor
CardInfo::CardInfo(Integer n) { deck_position = n; the_suit = new SuitInfo(n); the_pip = new PipInfo(n);}
CardInfo Object
Pip Pointer,PipInfo Object
Suit Pointer,SuitInfo Object
creates
![Page 39: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/39.jpg)
Summary of Memory Construction1 SimulationInfo
9 Cards1 Deck1 DeckInfo
4 Integers
52 Cards,52 CardInfos
52 Suits,52 SuitInfos,52 Pips,52 PipInfos
![Page 40: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/40.jpg)
Summary of Memory Construction (cont'd)
One simulation creates a total of 328 pointers and objects
If simulations were created over and over in a loop (very common with simulations in general), memory would be used up fast
This is a classic memory leak Solution: make sure that when a simulation is
over, all memory created by it is returned
![Page 41: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/41.jpg)
Recall flush Main Program
main() { Simulation s = new SimulationInfo; s->getdata(); s->simulate(); s->report(); s->free();}
The free method must make sure that all memorycreated by a simulation is returned (freed).
![Page 42: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/42.jpg)
SimulationInfo::free() Method
void SimulationInfo::free() { the_deck->free(); // Return memory for all cards delete [] one_hand; // Return memory for hand array delete [] suit_counts; // Return memory for suit counts // array delete this; }
one_hand and suit_counts, being arrays of primitive objects (pointer and Integer), can be returned using the C++ delete[] operator
The rest must be handled by the DeckInfo::free() method
![Page 43: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/43.jpg)
DeckInfo::free() Method
cd_array, being an array of pointers, can be deleted
However, each CardInfo object must be handled individually.
Note: cd_array must not be deleted first!
void DeckInfo::free() { for (Integer i = 0; i < 52; i++) // Return memory cd_array[i]->free(); // for each card delete [] cd_array; // Return memory
// for card array delete this;}
![Page 44: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/44.jpg)
CardInfo::free() Method
A SuitInfo and a PipInfo object are deleted Since the SuitInfo and PipInfo constructors
do not create any new objects, we are done.
void CardInfo::free() { delete the_suit; delete the_pip; delete this;}
![Page 45: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/45.jpg)
Simulating a Dynamic Multidimensional Array in C++
C++ only allows dynamic one-dimensional arrays.However, some structures are best thought of interms of rows and columns.
For example, a 4x4 matrix of cards.
So we must use the row and column to convert into asingle dimension index.
![Page 46: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/46.jpg)
Dynamic Multidimensional Arrays (cont'd)
An abstract 2-D array like:
is represented in memory as:
row
col
row * 4 + col = 2 * 4 + 2 = 10
0 10
0123
0 1 2 3
15
![Page 47: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/47.jpg)
Dynamic Multidimensional Array Example
CardArray cd_matrix;Integer row, column;Integer index;
row = 2;column = 2;cd_matrix = new CardInfo[4*4];index = row*4+column;cd_matrix[index] = new CardInfo(...);
Arrays of 3 dimensions and more must be handledsimilarly.
![Page 48: Implementing An OOD](https://reader035.fdocuments.in/reader035/viewer/2022062501/568167f1550346895ddd6374/html5/thumbnails/48.jpg)
Use of Constants
Using the preprocessor, as in:
#define PI 3.14159
should be avoided in C++. Why? Strictly speaking, the preprocessor is an extension to the language and not part of the language itself.
Instead, use the const declaration:
const Integer PI = 3.14159; const Integer NUM_TILES = 8;