1 / 38

Guidelines for Object-Oriented Programming in C++

Guidelines for Object-Oriented Programming in C++. Two Basic Steps. Convert a class diagram into C++ class declarations (header file) ‏ Write the class methods (implementation file) ‏. Separation of files facilitates procedural abstraction, data abstraction, and separate compilation.

jhenson
Download Presentation

Guidelines for Object-Oriented Programming in C++

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Guidelines for Object-Oriented Programming in C++

  2. Two Basic Steps • Convert a class diagram into C++ class declarations (header file)‏ • Write the class methods (implementation file)‏ Separation of files facilitates procedural abstraction, data abstraction, and separate compilation

  3. Elements of Good C++ Code • Readability • Consistent naming conventions • Code format • Comments • Language conventions • Coding style

  4. 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.

  5. Sample Script 8% flush Enter no. of cards in each hand (5-9): 7 Enter no. of hands to deal: 1000 DECK: 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 flushes 9%

  6. Chosen Object Classes • Simulation • Deck • Card • Pip • Suit

  7. 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

  8. Simulation Class Icon

  9. 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 . . .

  10. 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. };

  11. 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)‏

  12. 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

  13. Pointers and Objects (cont'd)‏ Use the pointer type Simulation when declaring: - variables - parameters - data fields Use the class type SimulationInfo to create an object with new. Once pointers exist, use the "->" form of reference for both method and data access. Finally, explicitly free all objects with delete.

  14. 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.

  15. flush Main Program main() { Simulation s = new SimulationInfo; s->getdata(); s->simulate(); s->report(); s->free(); }

  16. Naming Conventions in C++ Identifier TypeExamples Type name Integer Simulation State Method name solve simulate checkFlush Field name (data) flush_count problem problem_ Local variable i count Constant NUM_TILES

  17. Standard Types The basic type names of C++ do not conform to the naming 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;

  18. Memory Management Consider the SimulationInfo Constructor: 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 are allocated at run time.

  19. 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.

  20. 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

  21. Dangling Pointer References ptr = new ClassInfo(. . .); . . . delete ptr; . . . <code that later uses ptr again> ClassInfo Object ptr ptr Who knows what ptr is pointing to now. ptr ptr "Weird and wondrous" behavior ensues Partial Solution: follow the delete with ptr = NULL;

  22. Memory Leaks Suppose the following is in a loop: ptr = new ClassInfo(. . .); . . . <loop ends without any delete and ptr is no longer used> ClassInfo Object1 ClassInfo Object2 ClassInfo Object3 ptr ClassInfo Object4 ClassInfo Object5 . . .

  23. 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).

  24. Memory Management in the flush Program SimulationInfo Object creates creates creates Deck Pointer, DeckInfo Object Array of 9 Card Pointers Array of 4 Integers

  25. DeckInfo Class class DeckInfo { private: CardArray cd_array; // 52-element array to hold cards public: 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. };

  26. DeckInfo Constructor DeckInfo::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 creates Array of 52 Card Pointers, 52 CardInfo Objects

  27. CardInfo Class class CardInfo { private: Integer deck_position; // This card's deck_position Suit the_suit; // This card's suit Pip the_pip; // This card's pip public: 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. };

  28. CardInfo Constructor CardInfo::CardInfo(Integer n) { deck_position = n; the_suit = new SuitInfo(n); the_pip = new PipInfo(n); } CardInfo Object creates Suit Pointer, SuitInfo Object Pip Pointer, PipInfo Object

  29. Summary of Memory Construction 1 SimulationInfo 1 Deck 1 DeckInfo 4 Integers 9 Cards 52 Cards, 52 CardInfos 52 Suits, 52 SuitInfos, 52 Pips, 52 PipInfos

  30. 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

  31. 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 memory created by a simulation is returned (freed).

  32. 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

  33. DeckInfo::free() Method 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; } • 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!

  34. CardInfo::free() Method void CardInfo::free() { delete the_suit; delete the_pip; delete this; } • A SuitInfo and a PipInfo object are deleted • Since the SuitInfo and PipInfo constructors do not create any new objects, we are done.

  35. Simulating a Dynamic Multidimensional Array in C++ C++ only allows dynamic one-dimensional arrays. However, some structures are best thought of in terms of rows and columns. For example, a 4x4 matrix of cards. So we must use the row and column to convert into a single dimension index.

  36. Dynamic Multidimensional Arrays (cont'd)‏ An abstract 2-D array like: col 0 1 row 2 3 0 1 2 3 is represented in memory as: 0 15 10 row * 4 + col = 2 * 4 + 2 = 10

  37. 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 handled similarly.

  38. 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;

More Related