Upload
alicia-arnold
View
215
Download
2
Embed Size (px)
Citation preview
1
Object Oriented Programming
Winter 2002Drexel University
2
Course Information: Instructor : Anatoly Khusid
Email : [email protected] Web Page :
www.mcs.drexel.edu/~gakhusid/mcs350 Class : CS 350 Section 701 Term : Winter 2002 Time : Tue. 7:00 – 9:50pm Office Hours : By appointment only Help : Korman Center / Teaching and Learning Center
3
Course Objectives To provide solid background in objected
design and programming. To be able to recognize objects and
their associated behavior when building OO systems.
Use of inheritance and polymorphism in OO programs.
Understanding of UML, and using UML in OO design.
4
Course Objectives Hands on experience using OO design,
UML and implementation. Templates, software reuse, object libraries. Software patterns, and their applications. Exceptions and error handling, persistence Abstract Base classes Operator overloading Binding, Visibility, Scope and Access
Control
5
What are the pre-requisites for CS 350 ? CS 171, CS 172, and CS 270. This is not a course in C++, you should
have good working knowledge of non-object oriented C++.
Good understanding of how to create and define simple C++ classes and methods.
Knowing how to compile, run, debug and test C++ program.
We will only cover some of the advanced C++ features.
6
How CS 350 is structured:
Lectures: Lectures are not intended for
teaching how to write C++ code. In lectures you will learn OO
concepts. Whenever OO concepts require
examples, C++ code samples will used to explain the concepts.
7
How CS 350 is structured: Presentation:
Presentation will happen in small groups of two, where you will be asked to talk about certain subject for 10 minutes
You will be given at least 2 weeks to complete the homework or prepare for class presentation
Projects: Design and programming assignments. Done in Unix Departmental SunOS, and using Unix
Makefiles. You will be given at least 2 weeks to complete the project
You should follow directions on how to write and submit your project
8
How CS 350 is structured: Examinations:
Mostly OO concepts and design will be tested, as well as necessary knowledge of C++ code to demonstrate that you understood the concept.
Closed books, based on class notes and assigned readings from books
Class participation/attendance: Good participation and attendance can
make a difference!
9
Grading: Presentation : 5 % Projects : 40 % Midterm : 25 % Final : 25 % Quizzes, Attendance, Participation: 5
%
10
Online Course information: It is your responsibility to check
periodically course web page for updates, announcements, and posted assignments.
http://www.mcs.drexel.edu/~gakhusid/mcs350
11
Crash review of C++
Why C++ over C?
C++ allows OO support C++ has better and wider library
support. Example: STL Constant and reference variables Function overloading Operator overloading
12
Crash Review of C++Header files:
Include C++ library:#include <iostream>Include C library:#include <stdio.h>Include of user defined data type and
functionality or User defined C++ class.#include “MyClassA.h”
13
Comments: Should be neat, clear, not very long, easy
to understand for others. Every file should start with a header
comment block in the following general format:
/********************************File: wm.cDate: 1/1/99Purpose: Widget manipulationVersion: 1.0Author : John SmithCopyright: 2001 Ulticom, Inc **********************************/
14
Comments: Exact rules for commenting vary for each organization
and/or project, but general structure is preserved in every successful Software company.
Comment every function/method with the comment block describing function’s purpose, Pre-Conditions, Post-Conditions and/or Input/Output.
/* Purpose: Displays current time on the
screen. Input: None Output: 0 is returned when success and time is displayed. 1 is returned when something is wrong, and no time is displayed. */
int display() const;
15
Comments: Comment complicated algorithms used in
the program. General word of advice: Do not over-
comment, and do not under-comment ! Do not use meaningless comments such
as: “This is the constructor/destructor” “This is a loop variable” “This is public data”. These comments are useless and will only
make others, including yourself, confused.
16
Why Comments: Programmers can go into any code and figure
out what's going on New people can get up to speed quickly People make fewer mistakes in consistent
environments Your code MUST be well-commented. Period. It is desirable to have a consistent
commenting convention so as to facilitate the automatic extraction of comments from the source code
17
Some coding standards
1. Use pointers to represent classes.
2. Use the most restricted protection levels possible.
3. Data elements should always be private or protected.
4. Avoid the use of friend declarations.
5. Use const as much as possible
18
Using pointers to represent classes – why not? With pointers, have to use “new” and use lessefficient heap storage. Also have to rememberto deallocate storage with “delete” Without pointers, just use ordinary local or global
variables. Pointerless usage of objects is more efficient, less
complicated code (in C++): Better performance ( runs faster ) Easier to program
19
Consistency of pointer usage We need consistence when viewing objects.
Consistency: always using aptr->method() instead of *(aptr).method()
If it is not a pointer, use a.method(). Once you decide to go with one or another
style, you have to be consistent as much as possible
20
One advantage of using pointers Fewer inadvertent errors: with pointers, no
implicit calls to constructors, destructors, or conversions. Everything must be called explicitly.
Example:Car p; // implicit Car::Car() constructorCar* p = new Car(); // Explicit Car::Car constructorCar y=x; // Implicit copy constructor Car::Car(Car & c)Car y(x); // Same as aboveCar * y = new Car(x); // Explicit copy constructor Car::Car(Car & c)
21
Explicit/Implicit ? As we see pointers make everything explicit
and less confusing to the programmer. Instead of relying on C++ default(implicit) actions, sometimes programmer wants to have explicit control to avoid misunderstandings
Bellow two statements are identical, in both cases Car::Car(Car & ) copy constructor is invoked. Programmer can misinterpret first statement to be an assignment operation( calling operator= function )
Car x=y;Car x(y);
22
Explicit constructor C++ allows the programmer to reinforce ONLY
explicit invocation of the given constructor. Example:
class Car {explicit Car(const Car & car);
};int main(){
Car y;Car x=y; // error, because copy constructor now must only be // called explicitlyCar x(y); //ok return 0;
}
23
Using public, protected, and private Declaring the most restricted protection
possible allows the reader to know the intended scope of each method.
Forcing a class’ use to be only through its interface tends to simplify class programming and invocation
Let the compiler do protection checking.
24
Public selectionOnly put an object's interface in thepublic section. DO NOT expose anyprivate data items in the publicsection. At least encapsulate accessvia access methods. Ideally yourmethod interface should make mostaccess methods unnecessary. Do notput data in the public interface.
25
Friends Two types of friends: Procedures:
Friends are procedures that have access to private members of another class, but are not members of a class.
Class: Friend can also be another class. Friend class is allowed to access
private attributes of another classclass Node {
friend class List;//…
};List contains many nodes, and list methods can modify private attributes of
class Node
26
Friends A class can chose it’s friends A class that has friends is open to
corruption by those friends, therefore a class must chose its friends wisely
void List :: add( Node & node) {// Do something nasty to Node’s private
attributesNode.data = null;}
27
Friends They make life more complicated for theprogram reader because they introduce anexception to the general rules regardingclass protection. But:
it helps define some overloaded operators it’s the only feasible way to allow access to a very
closely related class, e.g. an iterator class needing access to a list class.
28
The uses of const const keyword helps the compiler to
reinforce the programmer’s intensions. The uses of const
const Car * const c = new Car(); const Car implies that Car’s attributes are read
only. Place where it points to. * const -- pointer itself is read only
29
More coding standards Use pass by reference whenever using non-simple
type objects, this prevents unnecessary memory copies.
Use simple types for parameters whenever is possible. This makes your program easier to read
Don’t abuse excessive function signature overloading. This makes it harder for programmer to predict which function will be invoked.
Only overload operators that make sense Avoid non-class storages ( C style struct )
30
Simplify reading Simplify reading:
– reduce the number of methods the programmer needs (e.g. in a graphics package with a lot of settable properties of distinct types use only setProperty(property, value) instead of a different method for setting each kind of property
Default parameters are not as bas as overload methods
void setColors(const char *, const char * = NULL, const char * = NULL);
31
More coding standards Define a constructor/destructor for each
class. Hence, Reiss’ recommendation to create a
constructor for each class, even if it does nothing much – don’t let the reader guess whether this is so.
Define both a copy constructor and an assignment operator for any class that is to be passed as a structure.
32
Yet more coding standards Always check array indices against
their bounds A class is responsible for its own data. Assign an owner to each object whenever
possible. Use typedef extensively Use enumerations to define any related set
of constants and all class constants
33
Memory management is one ofthe worst problems in using C++ Array out of bounds
– Check yourself, or use a class that has bounds checking built into it
Dangling references (freed storage still has pointers to it) – Aid: set any pointer to an object to NULL
when deleting the object. Memory leaks
34
Memory Management Three types of memory
Run-time stack All function calls, local variables are allocated on the run-
time stack When function returns (pops out from stack), all data that
was allocated on the stack for this function is freed automatically
We know in advance how much memory we want to allocate on the stack ( at a compile time )
Static data All variables declared outside functions, and class variables
declared static Come alive before main(), and persist before main() exits Static variables sometimes called “automatic”
Example: int x; // before main()
35
Memory Management Heap or free store
Part of the memory is used for dynamic allocation of memory; using C++ new, or C memalloc()
Must be explicitly freed using free(), or delete No need to do it in Java
If you don’t supply a destructor, compiler will provide you with default destructor. Default destructor only deallocates all the objects on the stack. By default, objects allocated on the heap, are left in the memory, and this memory becomes lost.
Variables allocated on heap sometimes called “dynamic variables”.
36
A tactic (heuristic) for memorymanagement Assign each dynamically created object an
owner (another object). The owner is responsible for deleting the object when it is finished with it. Include this in the documentation. But this is not always possible (e.g. when creating a library that makes objects for other programs to use, the library writer can’t assign ownership to any routine in the library).
37
Types and Variables:Basic types ( supported in C )int Integerchar Integer holding character
value is only one byte long.float/double Single precision floating point
numbers.
C++ Types: string and etc. Can construct new types by using
enumerated types and typedef:
enum Color { red, blue, green };typedef unisgned int size_t;
38
typedef Typedefs are useful in situations where you’re
defining pointers to functions void error(string s){ /* … */ } typedef void (*PF)(string); void (*efct)(string) = &error; PF * efct = &error; // Same as above
efct is a pointer pointing to function void error(string s) efct(“test”); //ok (*efct)(“test”); //ok
39
Compiler pre-processor directives: Pre-processor directives are processed
before compilation begins. Help avoiding multiple declarations of
the same prototype. If used wisely can improve compile time
for large project. Largely used when porting from one
platform to another using the same source code.
40
Pre-processor directives and C++ classes It is a good programming practice to surround
each class declaration by pre-processor directives.
Example:#ifndef _MY_CLASS_A#define _MY_CLASS_Aclass MyClassA {
…};#endif
This prevents multiple declarations, and allows the programmer to include the same header file more than once
41
Operators Arithmetic operators: +,-,/ and etc Bit operators ~ ,|=, & and etc Relational and Boolean: ==, <, >,
&& || and etc Assignment: x=1; x=y=1; x+=4; x=f();
42
Arrays Basic arrays do not check if
subscript is out of bound. Smart arrays ( objects ) prevent
out of bound access, and do dynamic shrinking and growing.
43
Statement blocks. In C++, statement blocks are delimited by
{ … } All automatic variables declared inside the
statement block will be de-allocated automatically when execution control leaves the block.
Dynamic data must be explicitly de-allocated by the programmer using delete/free() calls, otherwise you will have memory leak.
44
Word on global variables and constants Use of global variables usually is not a good
idea unless they are constants. Constants can be replaced by #define pre-
compiler directive. Namespaces are used in C++ to control
access to the variables, objects, and functionsnamespace lib1{ const double pi = 3.141592;}using namespace lib;using namespace lib:pi;
45
Why C++ has reference, and C does not? Call by reference is really a pointer to
the object. C++ introduced concept of references
for simplicity, and avoiding unnecessary use of pointers.
References must always be initialized, in pointers initialization is optional.
Using object’s reference is more efficient, uses less memory, and CPU time making unnecessary copies.
46
Returning references Do you see a problem here?String & getName(){
String aux;cin>>aux;return aux;
}
47
Keyword “this” C++ provides the programmer
with the keyword “this” “this” is a pointer to self Provides ambiguity resolutions
int Add::add(int x) {
this->x = x;}
Convenient way to address yourself from class methods
48
References - Side Effects? So far references are great! But what
about side effects? If referenced object goes out of scoop, and
you still use this reference, your program might crash.
Its not a good idea to return references from function calls when referenced object will go out of scoop when function returns.
Returning reference to the static data types from function might be acceptable.
49
Word on static static is a keyword in C/C++. Data type can be static, function can
also be static. Class methods can be static, and class
data can be static as well. Static data is initialized before program
starts execution. Global static variables are limited to the
scope of the file in which they are included.
50
Static example// Student.hclass Student {
public:static int count;
};// Student.C// Static variables are allocated and initialized before creating an instance of
class Student Student::count=0;int main() {
Student list[100]; // All 100 instances share the same variablereturn 0;
}
This might become a problem in multithreaded program where more than one thread tries to update the same variable, must remember to use Mutex
51
namespace A namespace is a mechanism for expressing
logical grouping. That is, if some declarations logically belong together according to some criteria, they can be put in a common namespace to express that fact. (Stroustrup)
Namespace grouping can apply to functions and classes
Namespaces can be nestednamespace Library{
namespace IO {// …
}}
52
Namespacesnamespace Parser {
void process() { /* process word */ }void analyze() { /* analyze syntax */ }
}Namespace CPU {
void process() { /* process I/O */ }void analyze() { /* analyze IRQ */ }
Namespaces allow programmers to create localized packages, this helps resolving ambiguities between different functions having the same names
53
Namespaces - using using namespace Parser;
Working in the scope of namespace Parser using namespace CPU;
Working in the scope of namespace CPU Direct resolutions:
Parser::process() CPU::process()
Sometimes we only want an access to one function in the given namespace
using Parser::process; process(); // Invokes Parser::process()
54
Name control Name Lookup
void X::fun() {
int x;{
x}
}
First we search the local scope, then for the operations in the scope of the class X, and then in the scope of the file ( among global variables )
55
Name control Functions
Functions are looked up first in the class scope if they are invoked from a method, next global scope is searched
If the same function in the global scope exists as in local, you can use resolution operator
void Test::func() {::f(); // Calls global function f()Test::f(); // Calls class method f()}
56
Class scope Enumerations class Date {
public:enum Weekday{MON, TUE, WED, THU, FRI, SAT,
SUN};//…
}; The above enumerations can be accessed from other functions
and/or classes by doing Date::MON
Enumerations can be private, in which case they are accessible only to the operations of the class
Moving enumerations into a class whose operations or clients are most likely to use them removes them from the global name space and minimizes the risk of conflicts
57
Nested classes A class can be nested inside another. This is
most frequently done to hide class that is relevant only for implementation.class List {
public:// …private:class Link {// …};Link * ln;
};Class Link is hidden from the outside world
58
Input/Output Iostream library is used to facilitate C+
+ I/O operations. cout/cin are equivalent of
printf()/scanf() in C. C++ I/O library makes programmer life
easy. Programmer does not have to worry about types displayed.
printf(“%d\n”, i); // Need to know that i is a digit
cout << i << endl; // no need to know what is the type of variable i
59
Why Objects ?
60
Why Objects? Why do we need to learn another way of
constructing software? Almost any software can be built in non-
object oriented languages like C, Pascal, Fortran.
But modern software projects are often to complex to be solved by traditional approaches. Constructing methods in C do not address the complexity of software.
61
The complexity of software We depend on software systems
Medical Financial Transportation Telephony systems
Failure of these systems sometimes have serious consequences.
Why do complex software systems fail? They are too complex to be accurately
modeled
62
Complexity of software: Large scale software systems are difficult and
complex to construct. Impossible for individual to comprehend all the
complexity of design Difficult to manage and fully accurately
specifying systems requirements The complexity of large systems generally
exceeds the human intellectual capacity Traditional and ad hoc software design
methodologies do not minimize the complexity
Need more disciplined ways to master complexity
63
Why Is Software so Complex? Complexity of managing systems
requirements Difficulty of managing the development
process The flexibility that is possible through
software The problems associated with
characterizing the behavior of discreet systems
64
System Requirements Managing contradictory requirements
Functional vs. non-functional requirements. Inability of users and developers to
effectively communicate requirements; users find it hard to give precise expression of their needs in a form that developers can understand
Requirements often change during development of a software system, leading to software preservation, not Software maintenance
65
The difficulty of Managing the Development process The task of every software development
team is to engineer the illusion of simplicity, shielding users from having to deal with unnecessary complexity
Even with modern tools and frameworks, large systems require hundred of thousands, or even millions lines of code.
More developers = more complex communication and management
66
Engineering the simplicity The more complex the system, the more
open it is to total break down. Software engineers are generally not
afraid to modify the system in ways that can lead to a total collapse of underlying design.
Failure to master the complexity results in projects that are late, over budget and deficient in their stated requirements
67
Five attributes of Complex systems
1) Most complex systems take the form of hierarchy; complex systems are composed as series of interrelated subsystems that have in turn their own subsystems. Eventually system is broken down to elementary component – unit.
68
Five attributes of Complex system
2) The choice of what components are primitive is relatively arbitrary. The selection of primitive components
is left up to the discretion of the observer or system designer.
3) Intra-component linkages are generally stronger than inter-component linkages.
69
Five attributes of Complex Systems
4)Hierarchic systems are usually composed for a few different kinds of subsystems in various combinations and arrangements Complex systems have common
patterns. Leverage reuse of primitive
components.
70
Five attributes of Complex Systems 5)Complex system that works is
invariably found to have evolved from simple system that worked Complex systems designed from scratch
rarely work As systems evolve, objects that were once
complex become primitive objects upon which more complex systems are built
We are generally unable to craft primitive objects correctly the first time
71
Solving Complexity Software systems are to complex to be
understood in a single chunk Divide programming task down into a set of
well defined chunks. Chunks are objects with specific and narrow responsibility
Chunks communicate with each other through well defined interfaces
Enables the programming task to be cooperatively solved by a set of communicating objects
72
Software Architecture As the size and complexity of software
systems increase Design and specifications of the overall system
structure becomes more significant than the choice of algorithms and data structures used for implementing the system
The software architecture of the system involves
Description of elements from which systems are built Interactions among elements Patterns that guide the composition of the elements
73
Procedural Decomposition: Programming task solved by breaking
down the problem into a large number of communicating procedures. Makes it complex to understand the overall behavior of the system and prone to errors.
Procedural Decomposition with subsystems: procedures that do a lot of communication are placed into a common subsystem. Easier to understand because complexity is encapsulated in the subsystems
74
Object Oriented Decomposition Programming task is solved by breaking
down the problem into a number of objects that communicate through well-defined interfaces. Objects manage their own state and protect
their data Easier to understand because complexity is
encapsulated in the objects Objects enforce that communication is
established through the defined interfaces.
75
Object Oriented Decomposition with subsystems
Sometimes the system is so large that we desire to combine the benefits of using objects and subsystems to facilitate the understanding of software architecture Cluster all related objects Each object is responsible for managing
its own behavior