Document 7143150

Download Report

Transcript Document 7143150

OOP Class
Lawrence D’Antonio
Lecture 4
An Overview of C++, Part 2
What is a class?
 A class is a set of objects sharing common




features.
A class defines an object’s attributes and
behavior. Methods are provided to act on
an object and to pass messages between
objects.
A class is the basic unit of abstraction.
A class is the basic unit of modularity.
A class can be concrete or abstract.
Class Design as Type Design
 Scott Meyers, Item #19
 How should objects of your new type be
created and destroyed?
 How should object initialization differ from
object assignment?
 What does it mean for objects of your new
type to be passed by value?
Class Design as Type Design 2
 What are the restrictions on legal values
for your new type?
 Does your new type fit into an inheritance
graph?
 What kind of type conversions are allowed
for your new type?
 What operators and functions make sense
for the new type?
Class Design as Type Design 3
 What standard functions should be




disallowed?
Who should have access to members of
your new type?
What is the “undeclared interface” of your
new type?
How general is your new type?
Is a new type really what you need?
What is an object?
 An object is an instance of a class.
 An object has state, behavior, identity.
What is an object?
Coad-Yourdon
An abstraction of something in a problem
domain, reflecting the capabilities of the
system to keep information about it, interact
with it, or both; an encapsulation of attribute
values and their exclusive services.
What is an object?
OMG
An object is a thing. It is created as the
instance of an object type. Each object has
a unique identity that is distinct from and
independent of any of its characteristics.
Each object offers one or more operations.
What is an object?
Firesmith
An object is defined as a software abstraction that
models all relevant aspects of a single tangible or
conceptual entity or thing from the application
domain or solution space. An object is one of the
primary entities in an object-oriented application,
typically corresponds to a software module, and
consists of a set of related attribute types,
messages, exceptions, operations, and optional
component objects.
What is an object?
Booch
From the perspective of human cognition, an
object is any of the following:
 A tangible and/or visible thing.
 Something that may be apprehended
intellectually.
 Something toward which thought or action is
directed.
What is an object?
Booch continued.
An object has state, behavior, and identity;
the structure and behavior of similar objects
are defined in their common class; the terms
instance and object are interchangeable.
What is an object?
Shlaer-Mellor
An object is an abstraction of a set of realworld things such that:
 All the things in the set have the same
characteristic.
 All instances are subject to and conform to
the same set of rules and policies.
What is an object?
Jacobson
An object is characterized by a number of
operations and a state which remembers the
effect of these operations.
What is encapsulation?
 Internal details of objects are concealed
from the objects users (information hiding).
 Both data and implementation may be
hidden. The object is a black box.
 Access to members is controlled through
the class definition.
 The accessible part of a class is called its
interface.
Data encapsulation example
class Clock {
private:
int hours; // 1-12 private
int minutes; // 0-59
public:
Clock(int h, int m) {
if (h < 1 || h > 12) {
throw(”Hours must be between 1 and
12″);
}
if (m < 0 || m > 59) {
throw(”Minutes must be between 0 and
59″);
}
h = hours;
m = minutes;
}
//...
};
Class Invariants
 The above is an example of “Programming by
Contract.”
 The class guarantees that
1  hours  12, 0  minutes  59
 These are called class invariants
Data Members
Data members can be declared as:
 const – a declaration that an object is read
only. The object may be stored in a CPU
register.
 volatile – a declaration that an object’s
value may be changed asynchronously.
The object may not be stored in a CPU
register.
Data Members 2
 static – A data member shared by all
objects of a class. There is only one copy
of a static member, it is not part of the
object memory layout.
 mutable – A data member that is allowed
to be modified, even if it a member of a
const object.
Is the following code legal?
struct X {
static int a = 2;
};
main()
{
X my_x;
X::a = 4;
my_x::a = 5;
}
Not legal!
Cannot initialize static data member a
within class.
static variables are similar to extern
variables.
Is the following code legal?
struct X {
static int a;
};
main()
{
X my_x;
X::a = 4;
my_x::a = 5;
}
Not legal!
This is a linker error.
X::a was used but never defined.
Is the following code legal?
struct X {
static int a;
};
int X::a;
main()
{
X my_x;
X::a = 4;
my_x::a = 5;
}
Legal.
X::a was defined before being used.
Note: it is okay that X::a was not initialized.
Is the following code legal?
struct X {
static int a;
static const int b = 3;
};
int X::a = 2;
main()
{
X my_x;
X::a = 4;
my_x::a = X::b;
}
Legal.
static const members can be declared
and defined at the same time.
Is the following code legal?
void func(volatile std::list<int> li)
{
int n = li.front();
}
Not legal!
Only volatile member functions can be called on a volatile
object.
list::front() not a volatile function
What is a method?
 A method is a member function that acts
upon an object. A method is generally
called for one object (exception: static
members).
 Commonly found methods are
constructors, destructors, assignment,
mutators, accessors.
Static Members
#include <iostream>
using namespace std;
class X {
public:
int a;
void f(int b) { cout << “X::f()\n”;}
};
int main() {
int X::*ptiptr = &X::a; //pointer to data member
void (X::* ptfptr) (int) = &X::f; //pointer to member function
X xobject;
xobject.*ptiptr = 10;
(xobject.*ptfptr) (20);
}
What is message passing?
 Messages are transfers of data or
requests for another object to take an
action.
Message passing example
 Adapter pattern
What is polymorphism?
 Different types of objects respond to the
same message and use the appropriate
method.
Parametric
Universal
Subtype
Polymorphism
Overloading
Ad-hoc
Coercion
Polymorphic Objects
 A function (or operator) is polymorphic if it
has an argument that can accept different
types.
 A variable is polymorphic if it can have
different types in different contexts.
 A type is polymorphic if its operations can
apply to arguments of different types.
Overloading
 The same name is used to denote
different functions.
 These functions are distinguished by
different signatures.
 Some languages (such as C++) allow the
programmer to define their own
overloaded functions and operators.
Overloading Example
int square(int x) { return x*x; }
long square(long x) { return x*x; }
float square(float x) { return x*x; }
double square(double x) { return x*x; }
Alternative Method
template<typename T>
T square(T x) { return x*x; }
This works on all data types for which operator * is
defined.
int x = square(4); //Calls square(int)
double y = square(4.2); //Calls square(double)
float z = square(3); //Calls square(int)
Implementation
 How is overloading done?
 Through name mangling. The compiler modifies
the names of each overloaded function.
 Example
void foo(int,int);
void foo(double,double);
In Assembler, these would be renamed:
foo_Fii:
foo_Fdd:
Is this code legal?
#include <stdlib.h>
struct C1 {enum E {red, blue};};
struct C2 {enum E {red, blue};};
extern "C" int printf(const char *, ...);
void f(C1::E x) {printf("f(C1::E)\n");}
void f(C2::E x) {printf("f(C2::E)\n");}
int main() {
f(C1::red);
f(C2::red);
return EXIT_SUCCESS;
}
Yes, this is legal.
The nested enums C1::E and C2::E are
different types. So the overloaded functions
have different signatures.
Is this legal?
class X {
public:
int f();
double f();
};
No, you can’t overload only on return type.
Is this legal?
struct A {
static int f();
int f();
};
No, it’s not legal. You can’t overload by
static.
Is this legal?
typedef int I;
void f(float, int);
void f(float, I);
Not legal. A typedef of an int is still an
int.
Is this legal?
f(char*);
f(char[10]);
Not legal. The arguments are considered the
same type (pointer to char).
Is this legal?
g(char(*)[20]);
g(char(*)[40]);
Yes, it’s legal. You can distinguish
multidimensional arrays by their second (or
higher) dimensions.
Is this legal?
int f(int);
int f(const int);
Not legal. You can’t overload by constness
of argument.
Is this legal?
void f(int &) { std::cout << “int &\n”; }
void f(const int &) { std::cout << “const int &\n”;
}
main() {
f(3);
return 0;
}
Legal. const is used within a type specification.
Q: Which function is called?
A: f(const int &)
Is this legal?
void f(int) { std::cout << “int \n”; }
void f(int &) { std::cout << “int &\n”; }
main() {
f(3);
return 0;
}
Legal. The signatures are different.
Q: Which function is called?
A: f(int)
Is this legal?
void f(double int) { std::cout << “double \n”; }
void f(const int &) { std::cout << “const int &\n”;
}
main() {
f(3);
return 0;
}
Legal. The signatures are different.
Q: Which function is called?
A: f(const int &)
Is this legal?
void f(int);
void f(int i = 10);
Not legal. Can’t overload by default
arguments.
Is this legal?
void g(int (float));
void g(int (*)(float));
Not legal. Both functions take the same
argument (pointer to function of the same
type).
Coercion
 A coercion is an implicit type conversion.
This allows the programmer to omit a type
cast.
 There are three types of coercions:
 Compiler defined (such as promotions,
derived  base)
 Constructor
 User defined
Compiler defined coercions
 Simple example
double x;
x = 2; //2 promoted to double
Function call coercions
void foo(double x) { //... }
//foo() can be called with any type that can be
//converted to double
foo((short) 4);
foo(‘a’);
foo(3L);
foo(2.3F);
Is this legal?
#include <iostream>
void f(char a, int b)
{ std::cout << a << b << '\n'; }
void f(int a, char b)
{ std::cout << a << b << '\n'; }
main()
{
f('a','b');
return 0;
}
Not legal, it’s ambiguous.
Coercion vs. Overloading example
3 +
3 +
3.0
3.0
4;
4.0;
+ 4;
+ 4.0;
How does this work?
Explanations of example
 Four overloaded versions of operator +
 Two overloaded versions of operator +,
one for integers, the other for doubles. The
middle two calls in the example would use
coercion.
 One version of operator +, for doubles.
The first three calls in the example would
use coercion.
Derived to Base Conversion
 C++ will implicitly convert a pointer or
reference to a derived class to a pointer or
reference to the base class. This is
because the derived class has a copy of
the base class inside it.
 A pointer to the base class cannot be
converted to a pointer to the derived class.
Is this legal?
class A {};
class B: public A {};
class C: protected A {};
class D: private A {};
main() {
A *pa = new B;
pa = new C;
pa = new D;
return 0;
}
pa = new B; //Legal, B is an A
pa = new C; //Illegal, C is not an A
pa = new D; //Illegal, D is not an A
In the last two cases, the base class is
inaccessible.
Is this legal?
class A {};
class C: protected A {
public:
void foo() { A *pa = this; }
};
class D: private A {
public:
void foo() { A *pa = this; }
};
main() {
C c;
c.foo();
D d;
d.foo();
return 0;
}
Yes, it’s legal. Protected and private
inheritance exemplify a has-a relationship,
rather than an is-a relationship. Member
functions are allowed to convert pointer to
derived into pointer to base.
Pointer to Member Conversions
 What is the relationship between a pointer
to member of a base class and a derived
class?
Is this legal?
struct A {
int a;
};
struct B: public A {
int a;
};
main()
{
A a;
B b;
int A::*pa = &B::a;
int B::*pb = &A::a;
return 0;
}
Complicated.
int A::*pa = &B::a;
is illegal. Can’t convert pointer to derived
member to a pointer to base member.
int B::*pb = &A::a;
Is legal. Can convert pointer to base member to
a pointer to derived member.
Conversion Constructors
 Constructors that take a single argument
can be thought of as a type conversion.
struct X { X(int); };
 So that any code that expects an object of
class X can be passed an int that will
then be converted to an X.
Is this legal?
struct X { X(int){} };
void f(const X &) {}
void g(int) {}
void g(X) {}
main() {
f(3);
g(4);
g(X(5));
return 0;
}
f(3); //Legal, you can create a temp
//object X(3), which is passed to
//f()
g(4); //Legal, calls g(int)
g(X(5)); //Legal, calls g(X)
Is this legal?
struct X { X(int){} };
void f(X &) {}
void g(int) {}
void g(X) {}
main() {
int a = 2;
f(3);
f(a);
g(4);
g(X(5));
return 0;
}
f(3);
//Not legal, can’t use temp X object to initialize an X &
f(a);
//Not legal, can’t use temp X object to initialize an X &
g(4); //Legal, as before
g(X(5)); //Legal, as before
Is this legal?
struct X { X(int){} };
struct Y { Y(X) {} };
void f(Y) {}
main() {
f(3);
return 0;
}
Not legal.
Basically, only one level conversions are
allowed. Not allowed to convert int to X to Y.
Is this legal?
struct X { X(int){} };
void f(X) {}
void g(int) {}
void g(X) {}
main() {
int a = 2;
f(3);
f(a);
g(4);
g(X(5));
return 0;
}
f(3); //Legal, temp X is passed by value
f(a); //Legal, temp X is passed by value
g(4); //Legal, as before
g(X(5)); //Legal, as before
Parametric Polymorphism
 Parametric polymorphism parametrizes
the object type (e.g., a list class, where the
type of object stored is parametrized).
Template Functions
template<class T>
T max(T a, T b) {
return a > b ? a : b;
}
Is this legal?
int a,b = 6;
const int c = 3;
double x,y = 3.2;
a
a
x
x
=
=
=
=
max(b,4);
max(b,c);
max(y,3.3);
max(b,y);
a
a
x
x
=
=
=
=
max(b,4); //Legal, max<int,int>
max(b,c); //Legal, max<int,int>
max(y,3.3); //Legal, max<double,double>
max(b,y); //Illegal, no max<int,double>
A template function is called only when there is an exact
match for type parameters (only trivial conversions, such
as const int to int are allowed).
Better max?
template<class S, class T>
T max(S a, T b) {
return a > b ? a : b;
}
main() {
int a, b = 3;
double x, y = 3.2;
a
x
x
x
=
=
=
=
max(b,5);
max(y,5.4);
max(b,y);
max(y,b);
return 0;
}
a = max(b,5);
//Legal, returns 5
x = max(y,5.4);
//Legal, returns 5.4
x = max(b,y);
//Legal, 3.2
x = max(y,b);
//Legal, but
//returns 3.0!
Best max?
template<class R, class S, class T>
R max(S a, T b) {
return a > b ? a : b;
}
main() {
int a, b = 3;
double x, y = 3.2;
a
x
x
x
=
=
=
=
max(b,5);
max(y,5.4);
max(b,y);
max(y,b);
return 0;
}
Doesn’t compile. The function max() is
supposed to have 3 template parameters.
But each call only uses 2 parameters.
Try this max
template<class R, class S, class T>
R max(S a, T b) {
return a > b ? a : b;
}
main() {
int a, b = 3;
double x, y = 3.2;
a
x
x
x
=
=
=
=
max<int>(b,5);
max<double>(y,5.4);
max<double>(b,y);
max<double>(y,b);
return 0;
}
Subtype polymorphism
 Subtype (or inclusion) polymorphism
allows objects of a given type to be
substituted for by objects of a subtype.
What is inheritance?
 One class (derived/child) relies on the




definition of another class (base/parent).
Single vs. multiple inheritance
A method of sharing code or sharing
interface among classes.
Language may define a class tree (with
single root): Java, Smalltalk
Language may define a class forest: C++
What is typing?
 Static typing: Data type determined at
compile-time. Type must be declared.
 Dynamic typing: Data type may be
determined at run-time. Type need not be
declared.
 Strong typing: Variables are bound to a
specific type.
 Weak typing: A variable’s type may
change.
Varieties of typing
 Static and strong typing: Java, Pascal,
OCaml, Haskell
 Static and weak typing: C/C++
 Dynamic and strong typing: Python
 Dynamic and weak typing: PHP
Dynamic typing example
# Python example
class Cat: def speak(self): print "meow!"
class Dog: def speak(self): print "woof!"
class Bob: def speak(self): print "hello world!"
def command(pet): pet.speak()
pets = [ Cat(), Dog(), Bob() ]
for pet in pets:
command(pet)
Weak typing example
var x := 5;
var y := "37";
Print(x + y);
In Visual Basic this prints: 42
In JavaScript this prints: 537
What is exception handling?
 The mechanism used to report and
recover from abnormal states.
 When an error is detected, execution is
passed to a handler.