the quarks of object-oriented development deborah j. armstrong, cacm 49(2006), vol.2 p123-128...

106
The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 Construct Concept Definition Structure Abstraction creating classes to simplify aspects of reality using distinctions inherent to the problem. Class a description of the organization and the actions shared by one or more similar objects. Encapsulation restricts access to the data and behavior by defining a limited set of messages an object can receive. Inheritance allows the data and behavior of one class to be used as the basis for another class. Object an individual, identifiable item which contains data about itself and descriptions of its manipulations of the data. Behavior Message Passing the process by which an object sends data to another object or asks the other object to invoke an action. Method a way to access, set, or manipulate an object's information. Polymorphism the ability of different classes to respond to the same message and each implement it appropriately.

Upload: reginald-glenn

Post on 31-Dec-2015

221 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

The Quarks of Object-Oriented DevelopmentDeborah J. Armstrong, CACM 49(2006), vol.2 p123-128

Construct Concept Definition

Structure Abstraction creating classes to simplify aspects of reality using distinctions inherent to the problem.

Class a description of the organization and the actions shared by one or more similar objects.

Encapsulation restricts access to the data and behavior by defining a limited set of messages an object can receive.

Inheritance allows the data and behavior of one class to be used as the basis for another class.

Object an individual, identifiable item which contains data about itself and descriptions of its manipulations of the data.

Behavior Message Passing the process by which an object sends data to another object or asks the other object to invoke an action.

Method a way to access, set, or manipulate an object's information.

Polymorphism the ability of different classes to respond to the same message and each implement it appropriately.

Page 2: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Using Objects

Internal, and User-defined Data-types (Classes)

Declaration, Definition, Initialization

Usage via Name, Reference, or Pointer

Manipulating Objects in Expressions via Operators or Functions

Objects as Function Parameters

Scope and Lifetime

Automatic, Dynamic and Static Objects

Page 3: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Arrays

double x[100]; // x[0] ... x[99]double x[3] = {1.1, 2.2, 3.3};double x[] = {1.1, 2.2, 3.3};

double m[3][3], m1[3][3], m2[3][3];// Code that initializes m1 and m2 ...

// m = m1 * m2for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { double sum = 0.0; for (int k = 0; k < 3; k++) { sum += m1[i][k] * m2[k][j]; } m[i][j] = sum; }}

Page 4: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

C++ arrays use 0-origin subscripting and the elements are stored row-wise.

Warning: m[1,2] is a valid C++ expression, but it does not access a multidimensional array.

Multidimensional arrays are arrays of arrays.

int m[2][3] = {

{1,2,3},

{4,5,6}

};

m consists of two elements (rows), each a one-dimensional array of three elements.

int

1

m[0][0]

int

2

m[0][1]

int

3

m[0][2]

int

6

m[1][2]

int

5

m[1][1]

int

4

m[1][0]

Page 5: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Pointers

int* p;

int i = 3;

p = &i;

int j = 4;

P = &j;

*p = 5;

p = 0;

...

if (p != 0) cout << "Pointer " << p << " points to " << *p << endl;

int iint 3:int* p

int* :

int jint 4:int* p

int* : int i

int 3:

&x address of x*p indirection, value of object pointed to by p

Administrator
If p is a pointer - int* p-, *p is the value of the object pointed by p (i in our example)This -to put a star in a pointer- is called indirection
Page 6: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Pointers and Arrays

float x[5];

x[0]: x[1]: x[2]: x[3]: x[4]:

float float float float floatfloat[5] x :

float*

Conversion

Whenever x is used in an expression -except as the operand of &, sizeof or to initialize a reference - it is convertedinto a pointer to the first element of thearray.x is of type array of float, but used as pointer to float.

Page 7: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Arithmetic on Pointers

x + 2

x points to x[0]

x+i points to x[i]

*(x+i)is equivalent to x[i]

x+i is equivalent to &x[i]

Integers can be added (or subtracted) to a pointer to an array element.

It acts as offset. The result is a pointer of the same type, which points to the element the specified number of elements away.

x[0]: x[1]: x[2]: x[3]: x[4]:

float float float float floatfloat[5] x :

float*

Conversion

Page 8: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

float x[10];

// ... initialize x ...

float* left = &x[0];

float* right = &x[9];

while (left < right) {

float temp = *left;

*left++ = *right;

*right-- = temp;

}

float x[10];

float* p = &x[10];

while (p != x) *--p = 0.0;

Administrator
float* p = &x(10) // one after the last while (p != x) *--p = 0.0;// uno menos (last element) = 0.0// until the 1st// (inicialization)
Page 9: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

const Pointers, Pointers to const Objects

const float pi = 3.14159;

const float* p = &pi;

pi = 2; // Compile Error

*p = 2; // Compile Error

float a, b;

float* const p1 = &a;

*p1 = 10;

p1 = &b; // Compile Error

const float e = 2.718281828;

const float* const p2 = &e;

Read complex declarationsfrom the identifier backtoward the beginning of the statement.

C Programmers:Do not use #define to define symbolic constants,use const for individualconstants or enum forenumerations.

Page 10: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Runtime Array Size

// Create arrays with the

// desired number of elements

int n;

cin >> n;

double* const x = new double[n];

double* const y = new double[n];

// Read the data points

for (int i = 0; i < n; i++) {

cin >> x[i] >> y[i];

}

// Accumulate sums Sx and Sy

// in double precision

double sx = 0.0;

double sy = 0.0;

for (i = 0; i < n; i++) {

sx += x[i];

sy += y[i];

}

// Compute coefficients

double sx_over_n = sx / n; double stt = 0.0;

double b = 0.0;

for (i = 0; i < n; i++) {

double ti = x[i] - sx_over_n;

stt += ti * ti;

b += ti * y[i];

}

b /= stt;

double a = (sy - sx * b) / n; delete [] x;

delete [] y;

cout << a << " " << b << endl;

Page 11: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Pointer Operators*p Indirection

&x Pointer to object

a[i] Array subscript

p->m Class member selection

++p, p++Pre(Post)increment to next element

--p, p--Pre(Post)decrement to previous element

p+=n Increment by n elements

p-=n Decrement by n elements

p+n Offset by n elements

p-n Negative offset by n elements

new T Allocate object

new T[n]Allocate array of n objects

delete pDelete object

delete []p Delete array of objects

Page 12: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Classes

OO Programming Two Simple Classes An Array Class Class Templates Function Templates Exceptions Nested Classes Overview of C++ Programs

Page 13: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Today

Classes

Memory Management

Classes and Functions in Detail

Inheritance

Page 14: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

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.

Page 15: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

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

Page 16: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

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

Page 17: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Two Simple Classes

Classes are programmer-defined types.

class class-name; // Declaration

class class-name { // Definition

class-body

};

class Point {

...

};

Point a; // creates an object of type Point

Point square_vertices[4]; // creates an array of four Points

Remember the trailing semicolonin class definitions.

Page 18: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Mapping of Abstractions to Software

real world abstractions software

entity

attributes

behaviour

class Entityattribute1...

function1()...

Page 19: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

CRC Cards for Class Design

CRC Class-Responsibility-Collaborator

Class-Name

Responsibility 1Responsibility 2....

Collaborator 1Collaborator 2...

Page 20: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Point Line

Create from coordinates Compute distance to another

point Compute distance to a line Get x- and y-coordinates

Page 21: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Line Point

Create from two points Create from point and direction Intersect with another line Compute distance to a point

Page 22: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Point definition

typedef double Number;

class Line;

class Point {public: Point(); // Create uninitialized Point(Number x, Number y); // Create from (x,y) Number distance(Point point); // Distance to another point Number distance(Line line); // Distance to a line Number x(); // Get x-coordinate Number y(); // Get y-coordinateprivate: Number the_x; // x-coordinate Number the_y; // y-coordinate};

Class members: data members

member functions

Page 23: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Using Point Objects

#include <iostream>using namespace std;#include "Point.h"

int main() { // Read the coordinates of a point and print the distance // from the origin to the point. Point origin(0, 0);

Number x; Point p1(1, 2); Number y; Point* p_ptr; cin >> x >> y; p_ptr = &origin; Point p(x, y); cout << p_ptr->distance(p1) << e cout << origin.distance(p) << endl; return 0;}

Page 24: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Point origin

Point

:

float the_y float0.0

:

float the_x float0.0

:

Data members of a class should be declared privateto ensure that they are only accessed from withinmember functions.

class Point {public: ... Point(Number x, Number y); ... private: Number the_x;

Number the_y; };

Point origin(0, 0);

Page 25: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Line definition

class Line {public: Line(Point p1, Point p2); // Line through p with tangent <xDir, yDir> Line(Point p, Number xDir, Number yDir); Point intersect(Line line); Number distance(Point point); // Smallest nonparallel angle (radians) static Number parallelism_tolerance; private: // ax + by + c = 0 Number a; Number b; Number c;};

Page 26: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Using Line Objects

// Vertical line through origin

Line l1(Point(0,0), Point(0,1));

//"anonymous" point objects are used for this line

// Line through (1,2) in direction <1,1>

Line l2(Point(1,2), 1, 1);

Point intersection;

intersection = l1.intersect(l2);

cout << "(" << intersection.x() << "," << intersection.y()

<< ")" << endl;

Page 27: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Member Function Definition

Point::Point(Number x, Number y) { the_x = x; the_y = y;}Point::Point() {}Number Point::x() { return the_x; }Number Point::y() { return the_y; }Number Point::distance(Point point) { Number x_dif = the_x - point.the_x;

//member – member of the object passed Number y_dif = the_y - point.the_y; return sqrt(x_dif * x_dif + y_dif * y_dif);}Number Point::distance(Line line) { double result = line.distance(*this); return result;}

Page 28: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Shared Objects inside Classes: staticPoint Line::intersect(Line line) {

// Intersect with line. If the angle between the two lines

// is less than the parallelism_tolerance, return the point

// at infinity. The parallelism test computes the square of

// the sin of the angle. We assume that the tolerance is

// small enough for sin(theta) to be approximately equal to

//theta.

Number det = a * line.b - line.a * b;

Number sinsq = (det * det) / ( (a*a + b*b) * (line.a*line.a

+ line.b*line.b) );

if (sinsq < parallelism_tolerance * parallelism_tolerance) {

return Point(FLT_MAX, FLT_MAX);

} else {

return Point( (b * line.c - line.b * c) / det,

(c * line.a - line.c * a) / det );

}

}

Number Line::parallelism_tolerance = .01745; // 1 degree (in rad)

Line::parallelism_tolerance = .02618; // 1.5 degrees (in radians)

Page 29: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

An Array Class: Operator Member Functions

#include <iostream>#include "SimpleFloatArray.h"

void linefit() { // Create arrays with the desired number of elements int n; std::cin >> n; SimpleFloatArray x(n); SimpleFloatArray y(n);

// Read the data points for (int i = 0; i < n; i++) { std::cin >> x[i] >> y[i]; } // ... same as before ... }

Page 30: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Runtime sizing with size given as constructor argument.

Access to element i in array x by evaluation of x[i].

Automatic management of dynamically allocated memory associated with the array.

Automatically copy array elements when arrays are copied.

Assign one array to another, and assign one float value to every array element.

Ask array's size and resize an array dynamically.

Page 31: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Runtime sizing with size given as constructor

argument.

class SimpleFloatArray {

public:

SimpleFloatArray(int n); // Create array of n elements

SimpleFloatArray(); // Create array of 0 elements

...

private:

int num_elts; // Number of elements

float* ptr_to_data; // Pointer to built-in array of elements

};

SimpleFloatArray::SimpleFloatArray(int n) {

num_elts = n;

ptr_to_data = new float[n];

}

SimpleFloatArray::SimpleFloatArray() {

num_elts = 0;

ptr_to_data = 0;

}

Page 32: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Access to element i in array x by evaluation of

x[i].

class SimpleFloatArray {

public:

...

float& operator[](int i); // Subscripting

...

private:

int num_elts; // Number of elements

float* ptr_to_data; // Pointer to built-in array of elements

};

float& SimpleFloatArray::operator[](int i) {

return ptr_to_data[i];

}

Page 33: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Access to element i in array x by evaluation of

At(i).

class SimpleFloatArray {

public:

...

float& At(int i); // Subscripting

...

private:

int num_elts; // Number of elements

float* ptr_to_data; // Pointer to built-in array of elements

};

float& SimpleFloatArray::At(int i) {

return ptr_to_data[i];

}

SimpleFloatArray d(100);

cout << d[50] << .... cout << d.At(50),...

Page 34: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Automatic management of dynamically allocated

memory associated with the array: destructor

class SimpleFloatArray {

public:

...

~SimpleFloatArray(); // Destructor: destroy array

...

private:

int num_elts; // Number of elements

float* ptr_to_data; // Pointer to built-in array of elements

};

SimpleFloatArray::~SimpleFloatArray() {

delete [] ptr_to_data;

}

When invoked with a null pointer, delete and delete [] have no effect.

Page 35: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Automatically copy array elements when arrays are

copied: copy constructorclass SimpleFloatArray {

public:

...

SimpleFloatArray(const SimpleFloatArray&); // Copy Constructor

...

private:

int num_elts; // Number of elements

float* ptr_to_data; // Pointer to built-in array of elements

void copy(const SimpleFloatArray& a); // Copy in elements from a

};

SimpleFloatArray::SimpleFloatArray(const SimpleFloatArray& a) {

num_elts = a.num_elts;

ptr_to_data = new float[num_elts];

copy(a); // Copy a's elements

}

Page 36: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

void SimpleFloatArray::copy(const SimpleFloatArray& a) {

// Copy a's elements into the elements of *this

float* p = ptr_to_data + num_elts;

float* q = a.ptr_to_data + num_elts;

while (p > ptr_to_data) *--p = *--q;

};

or

void SimpleFloatArray::copy(const SimpleFloatArray& a) {

// Copy a's elements into the elements of *this

for(int i=0; i<num_elts; ++i)

ptr_to_data[i] = a.ptr_to_data[i];

}

Page 37: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Assign one array to another, and assign one float

value to every array element: copy assignment operator

class SimpleFloatArray {

public:

...

SimpleFloatArray& operator=(const SimpleFloatArray&);

...

private:

int num_elts; // Number of elements

float* ptr_to_data; // Pointer to built-in array of elements

void copy(const SimpleFloatArray& a); // Copy in elements from a

};

SimpleFloatArray&

SimpleFloatArray::operator=(const SimpleFloatArray& rhs) {

if ( ptr_to_data != rhs.ptr_to_data ) {

setSize( rhs.num_elts );

copy(rhs);

}

return *this;

} Assignment should work correctly when left and rightoperands are the same object.

Page 38: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Ask array's size and resize an array dynamically.

class SimpleFloatArray {

public:

...

SimpleFloatArray& operator=(const SimpleFloatArray&);

SimpleFloatArray& operator=(float); // Scalar assignment

int numElts(); // Number of elements

void setSize(int n); // Change size

private:

int num_elts; // Number of elements

float* ptr_to_data; // Pointer to built-in array of elements

void copy(const SimpleFloatArray& a); // Copy in elements from a

};

Page 39: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Class Templates

class SimpleFloatArray {

public:

SimpleFloatArray(int n);

SimpleFloatArray();

SimpleFloatArray(const SimpleFloatArray&);

~SimpleFloatArray();

float& operator[](int i);

int numElts();

SimpleFloatArray& operator=(const SimpleFloatArray&);

SimpleFloatArray& operator=(float);

void setSize(int n);

private:

int num_elts;

float* ptr_to_data;

void copy(const SimpleFloatArray& a);

};

Page 40: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Class Template Definition

template<class T>

class SimpleArray {

public:

SimpleArray(int n);

SimpleArray();

SimpleArray(const SimpleArray<T>&);

~SimpleArray();

T& operator[](int i);

int numElts();

SimpleArray<T>& operator=(const SimpleArray<T>&);

SimpleArray<T>& operator=(T);

void setSize(int n);

private:

int num_elts;

T* ptr_to_data;

void copy(const SimpleArray<T>& a);

};

Page 41: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Class Templates: Usage

#include <iostream>#include "SimpleArray.h"

void linefit() { // Create arrays with the desired number of elements int n; std::cin >> n; SimpleArray<float> x(n); SimpleArray<float> y(n);

// Read the data points for (int i = 0; i < n; i++) { std::cin >> x[i] >> y[i]; } // ... same as before ... }

Page 42: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Member function definition for class templates

void SimpleFloatArray::copy(const SimpleFloatArray& a) {

// Copy a's elements into the elements of *this

float* p = ptr_to_data + num_elts;

float* q = a.ptr_to_data + num_elts;

while (p > ptr_to_data) *--p = *--q;

}

template<class T>

void SimpleArray<T>::copy(const SimpleArray<T>& a) {

// Copy a's elements into the elements of *this

T* p = ptr_to_data + num_elts;

T* q = a.ptr_to_data + num_elts;

while (p > ptr_to_data) *--p = *--q;

}

Page 43: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Overview of C++ Programs

File sys.h File A.h File B.h

File main.C

#include<sys.h>

#include"A.h"

#include"B.h"

main() {

...

}

File A.C

#include"A.h"

(Code for A)

File B.C

#include"B.h"

(Code for B)

Class A Class B

Page 44: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Memory Management

Object Life Cycle: Construction

Allocation Preinitialization Initialization

Use Destruction

Cleanup Post cleanup Deallocation

Object Lifetime Static Objects Automatic Objects Dynamic Objects Preventing Dangling

References and Garbage

Page 45: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Object Lifetime

Static objectsallocated once and not freed until program termination.

Automatic objectsallocated when their declarations are executed and freed

automatically when the block containing them terminates.

Dynamic objectsallocated and freed in arbitary order under the programmers

control.

Page 46: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Class Noisy to trace object con/de struction

#include "Noisy.h"

Noisy func(Noisy n) { std::cout<< "inside func\n"; return n;}

int main() {

Noisy x("x");

std::cout<<"\ncalling func\n";

Noisy c = func(x);

std::cout<<"after func\n";

std::cout << '\n';

return 0;

}

Page 47: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

constructing: (name=x id=0)

calling func

copy construct: (name=x id=1) from: (name=x id=0)

inside func

copy construct: (name=x id=2) from: (name=x id=1)

destroying: (name=x id=1)

after func

destroying: (name=x id=2)

destroying: (name=x id=0)

Page 48: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Noisy.h#ifndef NOISY_H

#define NOISY_H

#include <iostream>

#include <string>

#include <sstream>

class Noisy {

static long objects_created;

long id;

std::string name;

public:

Noisy(std::string n=""): id(objects_created++), name(n) {

if (name == "") {

std::ostringstream n;

n << "obj_" << id ;

name = n.str();

}

std::cout<<"constructing: " << *this << '\n';

}

Page 49: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Noisy(const Noisy& n): id(objects_created++), name(n.name) {

std::cout<<"copy constuct: " << *this << " from: "

<< n << '\n';

}

~Noisy() {std::cout<<"destroying: " << *this << std::endl;}

Noisy& operator=(const Noisy& rhs) {

std::cout<<"assignment: " << *this << " = " << rhs << '\n';

name = rhs.name;

return *this;

}

friend std::ostream& operator<<(std::ostream& os, const Noisy &n) {

return os << "(name=" << n.name << " id=" << n.id << ')';

}

}; // class Noisy

long Noisy::objects_created = 0;

#endif

Page 50: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Static Objects

are allocated once and are not freed until the program terminates.

Scope: class scopeclass A { ...; static int a; ...};

A::a = 1;

file scope with external linkageextern int a;

int a = 1;

file scope with internal linkagestatic int a;

local scope{...; static int a = 1; ...}

Page 51: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Use the extern keyword to declare file scope names with external linkage; omit the extern keyword on their definitions.extern int a; // Declaration, external linkageextern Complex a; // Decalration, external linkage

int a = 1; // Definition, initialized to 1Complex c1; // Definition, default constructor

Avoid file scope objects with external linkage; use classscop instead.

extern const double c;extern const double k;

const double c = 3.00e8;const double k = 1.38e-23;

namespace PhysicalConstants {public: static const double c; ...}const double PhysicalConstants::c = 3.00e8;...

Prefer namespace scope names to file scope names.

Page 52: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

static Noisy s1("s1"); // File scope static object.

void fnc(int j) { cout << "-- starting fnc(" << j << ") --" << endl; static Noisy s2("s2"); if (j == 2) { static Noisy s4("s4"); } for (int i = 1; i <= 2; i++) { cout << "-- loop i=" << i << " --" << endl; static Noisy s3("s3"); } cout << "-- returning from fnc(" << j << ") --" << endl;}

int main() { cout << "-- main starts --" << endl; fnc(1); fnc(2); cout << "-- main ends --" << endl; return 0;} static Noisy s5("s5"); // File scope static object.

Page 53: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Automatic Objects

int main() { cout << "-- main starts --" << endl; Noisy a1("a1"); for (int i = 1; i <= 2; i++) { cout << " -- loop i= " << i << " -- " << endl; Noisy a2("a2"); // Object created each loop iteration. if (i == 2) { Noisy a3("a3"); // Object created if i == 2. } } cout << "-- loop is done -- " << endl; Noisy a4("a4"); cout << "-- main ends --" << endl; return 0;};

Page 54: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

void f2() {

cout << "-- f2 starts -- " << endl;

Noisy c("c");

throw "exception";

cout << "-- f2 ends -- " << endl;

}

void f1() {

cout << "-- f1 starts -- " << endl;

Noisy a("a");

f2();

Noisy b("b");

cout << "-- f1 ends -- " << endl;

}

int main() {

cout << "-- main starts --" << endl;

try {

f1();

} catch(const char*) {

cout << "Exception caught." << endl;

}

cout << "-- main ends --" << endl;

return 0;

}

Page 55: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Dynamic Objects

Constructionint* p = new int;

int* q = new int(3);

Rational* r = new Rational(8,9);

int* a = new int[n];

Destructiondelete p;

delete q;

delete r;

delete [] a;

The worst problems arise from bad deletions: deleting an object more than once deleting a pointer not obtained by new using the wrong form of new

Provide a default constructor for every class possible.

Match every invocation of new with exactly one invocation of delete of the same kind.

Page 56: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Preventing Dangling References and Garbage

Dangling Class Membersclass Dangle {

public:

Dangle() { p = new int(0);}

~Dangle() { delete p; }

private:

int* p;

};

void f() {

Dangle a;

Dangle b = a;

}

Dangle a

Dangle b

:

:

int0

int* p :int*

int* p :int*

Provide a copy constructor and an assignment operator for classes with a pointer data member that is deleted by the destructor.

Page 57: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Dangling Pointers to Automatic Objects

void dangle(int j) {

int* p;

if (j < 100) {

// Dangling reference created when this block terminates

int iarray[100];

p = iarray;

}

else p = new int[j];

for (int i = 0; i < j; i++) p[i] = i;

}

Avoid pointers to automatic objects.

Page 58: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Pointers Left Dangling by Function Calls

void f(int* x) {

// ...

delete [] x; // Causes dangling reference

}

void dynamic_dangle(int size) {

int* iarray = new int [size];

f(iarray);

for (int i = 0; i < size; i++) cout << iarray[i];

}

Don't delete a functions argument.

Page 59: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Garbage Memory / Memory Leaks (failing to delete) is the opposite of the dangling

reference problem.

Hold pointers in class objects and pair new and deletein the class's constructors and destructors.

Page 60: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

The Uses Relationship

If an object of one class sends a message to an object of another class, the first object is said to have a uses relationship with the second class.

How can the first object know the name of the object it wants to use?

Carget_gasoline(50€)

Where ?

Page 61: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

get_gasoline(50€, Aral)Car

class Car {public: void get_gasoline(GasStation &, double);};

void Car::get_gasoline(GasStation &s, double money) { ... gas_received = s.give_gasoline(money); ...}

GasStation station1(...);Car car1(...);car1.drive(...);car1.get_gasoline(station1, 50);car1.drive(...);

by parameter

Page 62: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Car1get_gasoline(50€) The gas

station

give_gasoline(50€)

give_gasoline(40€)

Car2

GasStation theGasStation(...);class Car {public: void get_gasoline(double);};

void Car::get_gasoline(double money) { ... gas_received = theGasStation.give_gasoline(money); ...}

Car car1(...);car1.drive(...);car1.get_gasoline(50);

by global object

Page 63: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

class Car {public: void get_gasoline(double);};

void Car::get_gasoline(double money) { ... GasStation station(...); gas_received = station.give_gasoline(money); ...}

Car car1(...);car1.drive(...);car1.get_gasoline(50);

create a local station

Page 64: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

class Car {private: GasStation *station;public: Car(GasStation *s,...): station(s) {...} void get_gasoline(double);};

void Car::get_gasoline(double money) { ... gas_received = station->give_gasoline(money); ...}

GasStation s(...);Car car1(s,...);car1.drive(...);car1.get_gasoline(50);

by construction

Page 65: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Carget_gasoline(50€)

Mapget_station()

by third-party class

class Map {private: GasStation *quadrant[4];public: GasStation* get_station(int,int);};GasStation* Map::get_station(int x, int y) { if(x>0) return (y>0) ? quadrant[0]:quadrant[3]; else return (y>0) ? quadrant[1]:quadrant[2];}class Car {private: Map myMap;public: void get_gasoline(double);};void Car::get_gasoline(double money) { GasStation *station = myMap.get_station(x,y); gas_received = station->give_gasoline(money); ...}

Page 66: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

by containmentclass Car {private: GasStation myStation;public: void get_gasoline(double);};void Car::get_gasoline(double money) { gas_received = station.give_gasoline(money); ...}

by inheritance

class Car: public GasStation {public: void get_gasoline(double);};void Car::get_gasoline(double money) { gas_received = give_gasoline(money); ...}

Page 67: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Functions and Classes Member Functions and Overloading Initialization Copying Conversion Operator Functions Assignment Special Operators Destruction Static Member Functions Friend Functions I/O Operators for Classes

Page 68: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Member Functions and Overloading

class Point {

public:

Point(); // Create uninitialized

Point(Number x, Number y); // Create from (x,y)

Number distance(Point point) const; // Distance to another point

Number distance(Line line) const; // Distance to a line

Number& x(); // Reference to x-coordinate

Number x() const; // Get x-coordinate

Number& y(); // Reference to y-coordinate

Number y() const; // Get y-coordinate

Number angle(Point p1, Point p3) const;

private:

Number the_x; // x-coordinate

Number the_y; // y-coordinate

};

Page 69: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Point p1(2, 3);

cout << p1.x() << endl; // Uses non-const x()

p1.x() = 1; // Uses non-const x()

p1.y() = 2; // Uses non-const y()

const Point p2 = p1;

cout << p2.x() << endl; // Uses const x()

p2.x() = 3; // Compile Error

p2.y() = 4; // Compile Error

Declare member functions that are not meant to altermember data const.

Page 70: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Initialization: Constructors

class Circle {public: Circle(double radius); // Of specified radius centered at origin Circle(Point center, double radius); // From center and radius Circle(Point p1, Point p2, Point p3);// From three points on circle Circle(LineSegment chord, Point p); // From chord and point on cir. Circle(LineSegment diameter); // From diameter // ...private: Point the_center; double the_radius;};

Circle::Circle(double radius) : the_center(0, 0) { the_radius = radius;}

Page 71: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

A member initializer does not need to be provided for a data member in

two cases:

1. The data member is of a built-in type. Its value is undefined.

2. The data member is of a programmer defined type. The default constructor is called.

A member initializer must be provided for a data member, if:

1. There is no default constructor for the member's type.

2. The data member is a reference.

3. The data member is declared const.

Avoid using the value of one member in the initializationfor another member.

Member initializations should appear in the order in which the members are declared.

Page 72: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Copying: Copy Constructor

Objects can be copied by assignment or by initialization: operator=(const C&) Copy constructor: C::C(const C&), C::(C&)

shallow copy versus deep copy C++ default copy constructor: shallow copy

Circle c1(Point(1,2), 10); // No copy

Circle c2(c1); // c2 initialized by copying c1

Circle c3 = 10; // Create Circle(10.0) then initialize

// c3 from it

Page 73: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

shallow copy

aSimpleFloatArray

int 5;

float*

bSimpleFloatArray

int 5;

float*

float1.0

float9.0

float5.0

float2.0

float1.0

Page 74: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

deep copy

aSimpleFloatArray

int 5;

float*

bSimpleFloatArray

int 5;

float*

float1.0

float9.0

float5.0

float2.0

float1.0

float1.0

float9.0

float5.0

float2.0

float1.0

Page 75: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Automatically copy array elements when arrays are

copied: copy constructorclass SimpleFloatArray {

public:

...

SimpleFloatArray(const SimpleFloatArray&); // Copy Constructor

...

private:

int num_elts; // Number of elements

float* ptr_to_data; // Pointer to built-in array of elements

void copy(const SimpleFloatArray& a); // Copy in elements from a

}

SimpleFloatArray::SimpleFloatArray(const SimpleFloatArray& a) {

num_elts = a.num_elts;

ptr_to_data = new float[num_elts];

copy(a); // Copy a's elements

}

Page 76: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

A class that has built-in pointer member data not referring to data shared with other objects should havea copy constructor.

The argument to a copy constructor should be a constreference.

Page 77: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Conversions

A constructor that can take a single argument defines a user-defined conversion.

A conversion function is a member function with the target type name following the keyword operator.

Such conversions are used in the argument matching process and in any other context in which C++ does automatic type conversion.

Page 78: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

class Boolean {

public:

enum constants { false = 0, true = 1 };

// Construction.

Boolean() {} // Construct uninitialized.

Boolean(int i) : v(i != 0) {} // Initialize to (i != 0).

Boolean(float f) : v(f != 0) {} // Initialize to (f != 0).

Boolean(double d) : v(d != 0) {} // Initialize to (d != 0).

Boolean(void* p) : v(p != 0) {} // Initialize to (p != 0).

operator int() const{ return v; } // Conversion to int.

Boolean operator!() const { return !v; } // Negation.

private: Boolean b1(Boolean::true); // Boolean(int)

char v; Boolean b2(3); // Boolean(int)

}; int* p_i =new int(3);

Boolean b3(p_i); // Boolean(void *)

Boolean b4(3.0); // Boolean(float)

Page 79: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Boolean has_real_solution(double a, double b, double c) {

// Does ax**2 + bx + c = 0 have a real solution?

return sqr(b) >= 4 * a * c;

}

if ( has_real_solution(a, b, c) ) {

// ...

return 1;

}

Provide conversion from one class to another with either the copy constructor or a conversion function, but not both.

class ComplexFloat {public: // ... operator ComplexDouble() const; // ...};class ComplexDouble {public: // ... ComplexFloat cf; ComplexDouble(const ComplexFloat&); ... // ... ComplexDouble cd = cf;};

Page 80: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

class ComplexInt {

public:

// ...

};

class ComplexFloat {

public:

// ...

ComplexFloat(ComplexInt);

// ...

};

class ComplexDouble {

public: ComplexDouble(ComplexInt); ComplexInt ci;

ComplexDouble(ComplexFloat); // ...

// ... double a = arg(ci);

};

// Principal value of the argument of z

extern float arg(ComplexFloat z);

// Principal value of the argument of z

extern double arg(ComplexDouble z);

Minimize the number ofuser-defined conversionsfrom any given type.

Working code can be broken by introducing new classes.

Page 81: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

class Array {

public:

Array(int n); // Create n element array of int's

Array(const Array&); // Copy array

Array& operator=(const Array&); // Assign array

// ...

};

// ...

Array a(5);

a = 5;

ComplexDouble toComplexDouble() const;

Avoid single argument constructors when possible.

Provide few user-defined conversions.

Declare single argument constructors when explicit.

Page 82: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Operator Functions Operators in C++ are specified (declared) and

implemented (defined) in terms of equivalent functions, but they are used as operators.

Complex& Complex::operator*=(const Complex& rhs) {

float original_real_part = real_part;

real_part = real_part * rhs.real_part - imag_part * rhs.imag_part;

imag_part = imag_part * rhs.real_part + original_real_part

* rhs.imag_part;

return *this;

}

Complex a(1,1);

Complex b(2,3);

a *= b; a.operator*=(b);

Page 83: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

All C++ operators can be defined for class objects, except:

. .* :: ?: new delete sizeof No new operator symbols can be invented. The 'arity', precedence and associativity of

programmer-defined operators follows that of built-in operators.

An unary operator can be defined by either a member function with no arguments or as a global function with one argument, etc.

Give operators conventional definitions.

Page 84: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

class Complex{

public:

...

Complex operator+(const Complex&) const;

...

}

Complex a;

Complex b;

b = a + 3.0; // 3.0 is converted to Complex(3.0)

b = 3.0 + b; // Compile error (3.0).operator+(b)

Complex operator+(const Complex&, const Complex&);

Complex a;

Complex b;

b = a + 3.0; // 3.0 is converted to Complex(3.0)

b = 3.0 + b; // 3.0 is converted to Complex(3.0)

Declare symmetric binary operators as global functions.

Page 85: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Declare asymmetric binary operators and unary operators that modify their operand as member functions.

Define symmetric binary operators to call theircorresponding asymmetric assignment operator.

Complex operator*(const Complex& lhs, const Complex& rhs) { Complex result(lhs); return result *= rhs;}

Never overload &&, || or , . Function call semanticdiffers from short-circuit semantic because all parametersmust be evaluated and the order of evaluation is unspecified.

Page 86: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Assignment

Assignment member functions should work correctlywhen the left and the right operands are the same.

A class that has built-in pointer member data that are not meant to point to shared data should have an assignment operator.

The argument to an assignment operator should be a const reference.

Assignment operator functions should return a reference to their left operand.

Page 87: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Static Member Functions

class ComplexFloat {

public:

ComplexFloat(float r, float i);

static ComplexFloat fromFile(istream& input = cin);

// ...

};

ComplexFloat ComplexFloat::fromFile(istream& input) {

float r;

input >> r;

float i;

input >> i;

return ComplexFloat(r, i);

}

ComplexFloat c = ComplexFloat::fromFile();

Page 88: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Friend Functions

class A;

class B {

double g() const;

double g();

double g(int);

void h();

};

class C {

public:

friend int f(double); // Global function: int f(double)

friend double B::g() const; // Member of B: double g() const

// Note: only one of B's g members is a friend

friend class D; // All members of D

friend A; // All members of A; A already declared

private:

friend void B::h(); // Member of B: void h()

};

Page 89: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Friend Usage Example: Container Iterator

int main() {

// Read list of values and find minimum.

List<float> list;

float val;

float minval = FLT_MAX; // Max float value, from float.h

while ( cin >> val) {

if (val < minval) minval = val;

list.add(val);

}

// Normalize values and write out.

for (ListIterator<float> i(list); i.more(); i.advance()) {

cout << i.current() - minval << endl;

}

...

Page 90: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

template<class T>class List {public: List() : first(0), last(0) {} ... void add(T x) { if (first == 0) first = last = new Node(x); else last = last->link = new Node(x); } void remove(T x); // ... friend ListIterator<T>;private: class Node { public: Node(T x) : link(0), datum(x) {} Node* link; T datum; }; Node* first; Node* last; };

Page 91: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

template<class T>class ListIterator {

public:

ListIterator(const List<T>& list) : cur(list.first) {}

bool more() const { return cur != 0; }

T current() const { return cur->datum; }

void advance() { cur = cur->link; }

private:

List<T>::Node* cur;

};

Page 92: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Exceptions: throwclass SubscriptRangeError {

public:

SubscriptRangeError(int i);

int badSubscript();

private:

int subscript;

};

inline SubscriptRangeError::SubscriptRangeError(int i) {

subscript = i;

}

inline int SubscriptRangeError::badSubscript() {

return subscript;

}

...

template<class T>

T& CheckedSimpleArray<T>::operator[](int i) {

if (i<0 || i>=num_elts) throw SubscriptRangeError(i);

...

Page 93: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Exceptions: try, catch

try {

int n;

cin >> n;

CheckedSimpleArray<float> a(n);

...

int j;

cin >> j;

float x = 2.1 * a[j];

...

}

catch(SubscriptRangeError e) {

cerr << "Bad subscript = " << e.badSize() << endl;

}

Use exceptions to decouple the treatment of "errors" fromthe code dealing with the ordinary processing.

Page 94: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Nested Classes

class Outer {

public:

...

class Inner1 {

...

}

...

private:

...

class Inner2 {

...

}

...

}

Within the enclosing class a nested class can be referenced to using just ist name.

From outside the enclosing class, a nested class may be refrenced via the scope resolution operator ::

Outer::Inner1

Use class nesting to group related classes that work together.

Page 95: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

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.

Page 96: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Inheritance in C++

base / derived class

public / private inheritance

non-virtual / virtual / pure virtual member functions

concrete / abstract classes

Page 97: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Mammal

speak()

Dog

bark()

Cat

mew()

class Mammal {public: speak();}

class Dog: public Mammal {public: void bark();}

class Cat: public Mammal {public: void mew();}

Page 98: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Public Inheritance, Non-Virtual Members

class Mammal { // base class

public:

void speak() {cout << "can't speak" << endl;}

};

class Dog : public Mammal { // derived class

public:

void speak() {cout << "wouf" << endl;}

void bark() {cout << "wouf wouf" << endl;}

};

class Cat : public Mammal { // derived class

public:

void mew() {cout << "mew mew" << endl;}

};

Mammal fred;

fred.speak();

Dog lassie;

lassie.speak();

lassie.bark();

Cat sue;

sue.speak();//since speak is not defined for Cat, //the output is "cant speak"

sue.mew();

Mammal* x = new Dog();// this is allowed !

x->speak();// "cant speak"

x = &sue;

x->speak();

Page 99: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Public Inheritance, Virtual Members

class Mammal { // base class

public:

virtual void speak() {cout << "can't speak" << endl;}

};

class Dog : public Mammal { // derived class

public:

void speak() {cout << "wouf" << endl;}

void bark() {cout << "wouf wouf" << endl;}

};

class Cat : public Mammal { // derived class

public:

void mew() {cout << "mew mew" << endl;}

};

Mammal fred;

fred.speak();

Dog lassie;

lassie.speak();

Cat sue;

sue.speak();

Mammal* x = new Dog();

x->speak();// "wouf" because speak is virtual

// x only can use "Mammal" functions

// because its a mammal

x = &sue;

x->speak();

Virtual member functions to supportpolymorphism.

Page 100: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Public Inheritance, Pure Virtual Members

class Mammal { // abstract base class

public:

virtual void speak() = 0; //pure virtual member function

};

class Dog : public Mammal { // derived class

public:

void speak() {cout << "wouf" << endl;}

void bark() {cout << "wouf wouf" << endl;}

};

class Cat : public Mammal { // derived class

public:

void speak() {cout << "mew" << endl;}

void mew() {cout << "mew mew" << endl;}

};

// Mammal fred;

// fred.speak();

Dog lassie;

lassie.speak();

Cat sue;

sue.speak();

Mammal* x[n];

x[0] = &lassie;

x[1] = &sue;

for(int i=0;i<n;i++) {

x[i]->speak();

}

x[0]->bark(); // Error

Abstract classes serve as interfaces.

Page 101: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

"abstract"

Mammal

speak()

Dog Cat

Page 102: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Private Inheritance

class Mammal {

public:

void speak() {cout << "can't speak" << endl;}

};

class Dog : private Mammal {

public:

void bark() {speak();}

};

class Cat : public Mammal {

public:

void mew() {cout << "mew mew" << endl;}

}

Mammal fred;

fred.speak();

Dog lassie;

lassie.bark();

lassie.speak(); // Error

Cat sue;

sue.speak(); //this works

Private inheritance to share implementation.

Page 103: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Public Inheritance, Virtual Members

class Mammal { // base class

public:

virtual void speak() {cout << "can't speak" << endl;}

};

class Dog : public Mammal { // derived class

public:

void speak() {cout << "wouf" << endl;}

void bark() {cout << "wouf wouf" << endl;}

};

class Cat : public Mammal { // derived class

public:

void mew() {cout << "mew mew" << endl;}

};

Mammal fred;

fred.speak();

Dog lassie;

lassie.speak();

Cat sue;

sue.speak();

Mammal* x = new Dog();

x->speak();

x = &sue;

x->speak();

Virtual member functions to supportpolymorphism.

Page 104: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Access to Base Class Members

class One {

public:

int element1;

protected:

int element2;

private:

int element3;

};

class Two : public One {

};

clients of Two

clients of Three

clients of Four

...

class Three : private One {

};

class Four : protected One {

};

class Five : public Three {

};

class Six: public Four {

};

Page 105: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

dynamic_cast<T>(), typeinfo#include <typeinfo>

Dog lassie;

Cat sue;

Mammal* m[3];

m[0] = &lassie;

m[1] = &sue;

...

for ( i=0;i<3;i++) cout << typeid(m[i]).name() << ", ";

cout << endl;

for ( i=0;i<3;i++){

Dog* d = dynamic_cast<Dog *>(m[i]);//0 or a valid pointer

if(d) d->bark(); // if the pointer is valid, bark

}

Page 106: The Quarks of Object-Oriented Development Deborah J. Armstrong, CACM 49(2006), vol.2 p123-128 ConstructConceptDefinition StructureAbstraction creating

Forms of Inheritance

Specialization: The derived class is a subtype, a special case of the base class.

Specification: The base class defines behavior that is implemented in the

derived class.

Construction: The derived class makes use of the behavior provided by the

base class, but is not a subtype of the base class.

Generalization: The derived class modifies some of the methods of the base.

Extension: The derived class adds new functionality to the base, but does not

change any inherited behavior.

Limitation: The derived class restricts the use of some of the behavior

inherited from the base.

Variance: The derived class and the base class are variants of each other,

and the base/derived class relationship is arbitrary.

Combination: The derived class inherits from more than one base class.