Date post: | 19-Dec-2015 |
Category: |
Documents |
View: | 217 times |
Download: | 0 times |
Overview: OO and C++
Software Engineering Goals and Strategies Programming Techniques C++ Structures What to Teach? What to Learn? Why C++? Why not C++?
Why Start with:
Software Engineering Goals Design Strategies Programming Techniques
Design skills are useful in the development of realistic programms.
Without understanding programming in the large, one cannot (and need not) understand the importance of OOP.
Design Strategies
Abstraction Simplifying the description of a real-world entity to its essentials.
Separation Treating what an entity does and how it does it independently of
each other.
Composition Building complex systems by assembling simpler parts via
association and aggregation.
Generalization Identifying common elements among different entities via
hierarchy, genericity, polymorphism or patterns.
Programming Techniques
Unstructured Programming Procedural Programming Modular Programming Object-Oriented Programming
Mapping of Abstractions to Software
real world abstractions software
entity
attributes
behaviour
data
functions
x- and y-intercepts of ax + by + c = 0
#include <iostream.h>
int main() {
// Read the coefficients of a line equation in the form
// ax+by+c = 0
// then print the line's x- and y-intercepts.
// Read the equation coefficients.
float a, b, c;
cin >> a >> b >> c;
// Print the equation coefficients.
cout << "Coefficients: " << a << ", " << b << ", " << c << endl;
// Compute and print the x-intercept. cout << "x-intercept: ";
if (a != 0) {
cout << -c / a << ", ";
}
else {
cout << "none, ";
}
// Compute and print the y-intercept.
cout << "y-intercept: ";
if (b != 0) {
cout << -c / b << endl;
}
else {
cout << "none" << endl;
}
return 0;
}
Procedural Programming
• The main program coordinates calls to procedures and hands on appropriate data as parameters.
main programdata
function3()function2()function1()
main function
/* Example: Stack C like */
#define MAXVAL 100 /* max stack depth */
int sp = 0; /* Stack pointer */
double val[MAXVAL]; /* Stack */
void push(double f ) {
if (sp < MAXVAL) val[sp++] = f;
else {
cout << "error: stack full\n";
clear();
}
}
double pop () {
if (sp > 0) return val[--sp];
else {
cout << "error: stack empty\n";
clear();
return 0;
}
}
int main() {
...
/* use the stack */
push(1); push(2); push(17);
d = pop();
...
}
Critique:
The code is readable and understandable. Functions (push, pop, ...) are used as
abstraction mechanism. The data contained in the stack cannot be made local
to any of the routines, they must be shared by all.
Solution: Modules
David Parnas 1982: information hiding principle
Provide an user of an abstraction with all information
needed to use it correctly, and nothing more.
Modular Programming
• The main program coordinates calls to procedures in seperate modules. Each module can have its own data.
main programdata
function3()function2()function1()
module 1data 1
module 2data 2
stack.h
#define MAXVAL 100 /* max stack depth */
void push(double f );
double pop ();
UseStack.c
#include "stack.h"
int main() {
...
/* use the stack */
push(1); push(2); push(17);
d = pop();
...
}
stack.c
int sp = 0; /* Stack pointer */
double val[MAXVAL]; /* Stack */
void push(double f ) {
if (sp < MAXVAL) val[sp++] = f;
else {
cout << "error: stack full\n";
clear();
}
}
double pop () {
if (sp > 0) return val[--sp];
else {
cout << "error: stack empty\n";
clear();
return 0;
...
Critique
Modules solve some but not all problems: Moduls permit to hide the implementation details. They do not solve the problem of instantiation,
the ability to make multiple copies of the data areas.
Solution: Classes and Objects What if you need stacks for different types?
Solution: Templates
Object-Oriented Programming
• The main program coordinates calls to procedures in seperate modules. Each module can have its own data.
object 1data 1
object 2data 2
object 4data 4
object 3data 3
class Stack {
public:
void push(double f);
double pop();
...
private:
int sp;
double val[maxval];
...
};
int main() {
Stack s;
Stack t;
s.push(1); t.push(2); s.push(17);
d = s.pop();
t.push(s.pop());
...
}
Stackint spdouble val[]...push(double)double pop()...
Stack s
sp
val
0
Stack t
sp
val
2
2 1
Implementation of the Stack Class
double Stack::push(double f ) {
if (sp < maxval) val[sp++] = f;
else {
cout << "error: stack full\n";
clear();
}
}
double Stack::pop () {
if (sp > 0) return val[--sp];
else {
cout<< "error: stack empty\n";
clear();
return 0;
...
Templates:
template <class T>
class Stack {
public:
void push(T f);
T pop();
...
private:
int sp;
T val[maxval];
...
};
int main() {
Stack<double> s;
Stack<double> t;
s.push(1); t.push(2); s.push(17);
d = s.pop();
t.push(s.pop());
...
}
classes with type parameters, generic classes
Object-Oriented Programming
Object-oriented programming views a program as collection of agents, termed objects. Each object is responsible for specific tasks.
An object is an encapsulation of state (data members) and behavior (operations).
The behavior of objects is dictated by the object class. An object will exhibit its behavior by invoking a
method (similar to executing a procedure). Objects and classes extend the concept of abstract data
types by adding the notion of inheritance.
Mapping of Abstractions to Software
real world abstractions software
entity
attributes
behaviour
class Entityattribute1...
function1()...
Variety of Classes
Domain Classes / Data Managers / Materials Classes whose principle responsibility is to maintain data
values
Data Sinks or Sources Objects that interface to data generators or consumers, but do
not hold data themselves
View or Observer Classes, Tool Classes Classes that provide the graphical display of an object, but are
not the object themselves
Helper Classes, Container Classes Classes that maintain little or no state information, but assist
in the execution of complex tasks
What Do Classes Represent
Classes that directly reflect concepts in the application domain.
Classes that are artifacts of the implementation.
User-level concepts (e.g. cars and trucks) Generalization of user-level concepts (e.g. vehicles) Hardware ressources (e.g. memory manager) System ressources (e.g. output streams) Helper classes (e.g. lists, queues, locks, ...)
8 5 2.0 6.0 2.0 2.0 4.0 4.0 4.1 1.0 6.0 5.06.0 2.0 8.0 3.0 9.0 1.0 3 1 2 0 3 3 2 13 5 2 3 4 6 4 2 5 3 7 6 5
1 2 3 4 5 6 7 8 9
1
2
3
4
5
6
0
1 2
3
4
(0)
(1)
(2)
(3)
(4)
(5)
(6)
(7)
Example: General Purpose Interface Bus (GPIB)
GPIB
An Acme 130voltage supply
A VoltyMetricsvoltmeter
Acme130
Acme140
Inheritance to Share Implementationclass Acme130 {public: Acme130(GPIBController_Stub& controller,int gpib_address); void set(float volts); double minimum() const; double maximum() const;private: GPIBController_Stub my_controller; int my_gpib_address;};class Acme140 : public Acme130 {public: enum Jumper { J1, J2 }; // Possible jumper settings Acme140(GPIBController& controller, int gpib_address, Jumper j); float maximum() const;private: float max_voltage;};
"interface"
Voltmeter"interface"
GPIBInstrument"interface"
VoltageSupply
VoltyMetrics Acme130 VoltOn59
Inheritance to Share Behavior, Polymorphism
"abstract"
VoltageSupply
void set(float)float minimum()float maximum()
Acme130 VoltOn59
float checkCalibration(VoltageSupply& supply, VoltyMetrics& meter, float tst_voltage) { // Relative error at specified test voltage. supply.set(tst_voltage); return abs(tst_voltage - meter.read()) / tst_voltage;}
class VoltageSupply {public: virtual void set(float volts) = 0; virtual float minimum() = 0; virtual float maximum() = 0; virtual ~VoltageSupply();};
class Acme130_VS : public VoltageSupply { ...};
Design Patterns
0
10
20
30
40
50
60
70
80
90
1. Qrtl. 2. Qrtl. 3. Qrtl. 4. Qrtl.
0
50
100
1. Qrtl. 2. Qrtl. 3. Qrtl. 4. Qrtl.
OstWest
Nord
1. Qrtl. 2. Qrtl. 3. Qrtl. 4. Qrtl.Ost 20,4 27,4 90 20,4West 30,6 38,6 34,6 31,6Nord 45,9 46,9 45 43,9
20,4 27,4 90 20,430,6 38,6 34,6 31,645,9 46,9 45 43,9 Subject
Observer
Observer Observer
change notification
modificationsrequests
Subject
Attach(Observer)Detach(Observer)Notify()
ConcreteSubjectsubjectStateGetState()SetState()
Observer
Update()
ConcreteObserverobserverStateUpdate()
observes
subject
return subjectState
observerState = subject-> GetState()
for all o in observers { o -> Update()}
C++ Structures:
variables/constants pointer, references, arrays expressions, operators control statements functions exceptions types/objects
builtin types classes
interface data members implementation
inheritance of interface of data members of implementation
polymorphism templates class libraries frameworks design patterns
Connections among Strategies, Structures and Goals
abstraction
separation
composition
generalization
classes/objects
inheritance
templates
design patterns
reusability
extensibility
flexibility
DesignStrategies
C++/OOStructures
SEGoals
Classes of Software
Application Programs Libraries, Toolkits
Applications will use classes from one ore more libraries of predefined classes.
Frameworks A set of cooperating classes that make up a reusable
design for a specific class of software.
Libraries
Application Librarye.g. Simulation
GUI• Graphics• Events
Database• OODBMS
OS Support• Net• Files• ThreadsDatastructures Algorithms
What to Teach? What to Learn?
How to think in objects? How to analyse object-
oriented? How to design object-
oriented? system design class hierarchy design class design
How to program in C++? C++ as better C using classes
class implementation memory management features and pitfalls
What is in the class library/framework? C++ standard library ...
How to use the tools? IDEs Compiler Debugger ...
Why C++ Why not C++
C++ is widely available and used.
C++ is the fastest OO language.
C++ is designed for a variety of programming paradigms.
C++ is mature.
C is a small language, C++ is a big language.
C++ is hard to learn.
C++ has subtle and often hard-to-predict behaviors.
C++ lacks an automatic garbage collection.