object oriented analysis & design
DESCRIPTION
Object Oriented Analysis & Design. Class Design 2. Contents. Class Design. How you design your classes impacts The efficiency of your program The architecture of your program The understandability of your program The maintainability of your program The total cost of the game. - PowerPoint PPT PresentationTRANSCRIPT
Object Oriented Analysis & Design
Class Design 2
2
Contents
3
Class Design How you design your classes impacts
The efficiency of your program The architecture of your program The understandability of your program The maintainability of your program The total cost of the game
4
The Well-Designed Class A well-designed class can
Be used anywhere in the program Be used in conjunction with STL containers Provide all methods that will ever be needed to
use the class in any situation Be serialized if the data needs to be sent across a
network or saved on disk Provide other classes access to the data they need Protect its data so other classes cannot corrupt it
5
The General Purpose Class A class which can be used almost anywhere
Defines a parameterless constructor Allows default instances to be created for making
arrays, STL containers and serialization Defines a copy constructor
Used when copying values to parameter lists and when returning classes from methods
An assignment operator Allows one object to be copied to another object
6
The General Purpose Classclass Weapon {private:
std::string name;float killRadius;float damageFactor;
public:Weapon(); // init all fieldsWeapon(const Weapon &other); // copy constructorWeapon operator=(Weapon &other); // assignment// other methods ...
};
7
Classes for Use with STL Classes used with STL must also define
Operator== Operator!=
8
Classes for Use with STLclass Weapon {private:
std::stringname;float killRadius;float damageFactor;
public:Weapon(); // init all fieldsWeapon(const Weapon &other); // copy constructorWeapon operator=(Weapon &other); // assignmentfriend bool operator==(const Weapon &w1, const Weapon &w2); // equalsfriend bool operator!=(const Weapon &w1, const Weapon &w2); // not equals
// other methods ...};
9
Planning for Debugging You WILL have to debug your game This will be likely done using a log file You will MOST LIKELY have a log file for your
game Any class might have to be printed as text
Therefore: Provide an insertion operator which can print a
textual version of the class for debugging purposes
10
Planning for Debuggingclass Weapon {private:
std::string name;float killRadius;float damageFactor;
public:Weapon(); // init all fieldsWeapon(const Weapon &other); // copy constructorWeapon operator=(Weapon &other); // assignmentfriend bool operator==(const Weapon &w1, const Weapon &w2); // equalsfriend bool operator!=(const Weapon &w1, const Weapon &w2); // not equalsfriend std::ostream& operator<<(std::ostream &os, const Weapon &w); // insertion
// other methods ...};
11
That Sounds like Too Much Work Building classes
correctly at the start Becomes automatic
and you do not think about it
They are ready for use anytime anywhere
You do not have to go back and do it later
12
Destructors A class needs a destructor if
It has open files which need to be closed It has open network connections which need to be
closed It has pointers to other objects which need to be
deleted It accesses any shared resource which needs to be
released It alters global variables to count number of
instances or some value that depends on the number instances of each class
13
Parameter Passing In C & C++
All parameters are passed by copying some value... In pass-by-value, the value of the parameter is passed In pass-by-reference, a pointer to the real value is copied
Use pass-by-value when You are passing a simple int, float, etc.
Use pass-by-reference when You are passing an object
Remember Arrays are ALWAYS passed by reference automatically
14
Passing By Reference is Easier A reference is
A pointer which cannot be modified When you pass by pointer
You must remember to dereference the pointer within the body of the method
When you pass by reference The references are generated automatically You do not need to dereference them within the
method body
15
Assigning Responsibility Often, we are faced with the question
“Which class should have this attribute?”
The general answer is The class who properly owns the attribute The class to which the attribute belongs
16
Assigning Responsibility Consider a game board with
objects on it Should the position of the objects be
stored As an attribute of the objects ? As an attribute of the game board ?
Consider the operations we will perform Render the game board & objects Move an object from one location to
another Determine which object was clicked
17
Option 1: Position Stored in Board
18
Option 1: Drawing
19
Option 1: Hit Detection
20
Option 1: Move a Piece
21
Option 2: Position Stored in Piece
22
Option 2: Drawing
23
Option 2: Hit Detection
24
Option 2: Move
25
Analysis of Option1 & 2 Option 1 (position in Board)
Pros Cons
Moving requires looking up the current location of the pice on the board, which will be an expensive operation.
You tell the board to move a piece rather than telling the piece to move itself. This is not natural.
Option 2 (position in piece) Pros
You tell piece to move itself and this is done efficiently and naturally.
It is easy to do hit detection and drawing
26
Analysis of Option1 & 2 Option 2 is
slightly easier to implement More natural and intuitive to use More efficient
Why? The position of a piece is a property of the piece,
not of the board The board should simply have a collection of
pieces In this case, the board uses a 2D array as a fast
index into the pieces
27
RTTI Run Time Type Identification
Requires classes to have at least 1 virtual function Adds to the memory requirements Can slow the program
Few programs must use RTTI Proper class design and use of polymorphism
can eliminate the need for RTTI
Remember: RTTI was a late addition to C++
28
Virtual Destructors Destructors, like other methods, can be
declared virtual Consider:
class Parent {private: int *intArray;public: ~Parent() { if(intArray) delete [] intArray; }};
29
Virtual Destructors class Child: public Parent {
private: char *charArray;public: ~Child() { if(charArray) delete [] charArray; }};
Parent *p = new Child(); delete(p); // invokes parent destructor!
The problem is that the wrong destructor is used
30
Virtual Destructors This problem can be fixed by declaring the
destructor virtual
class Parent {private: int *intArray;public: virtual ~Parent() { if(intArray) delete [] intArray; }};