c object oriented programming l.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
C++ & Object-Oriented Programming PowerPoint Presentation
Download Presentation
C++ & Object-Oriented Programming

Loading in 2 Seconds...

play fullscreen
1 / 104

C++ & Object-Oriented Programming - PowerPoint PPT Presentation


  • 88 Views
  • Uploaded on

C++ & Object-Oriented Programming. The Class. A class is a unit of encapsulation. Public operations, and private implementation. A class is an abstraction. String abstracts the char * of C, stack -- the canonical abstraction List Student, etc. Classes and C structures.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'C++ & Object-Oriented Programming' - kirti


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
a class is a unit of encapsulation
A class is a unit of encapsulation
  • Public operations, and
  • private implementation.
a class is an abstraction
A class is an abstraction
  • Stringabstracts the char * of C,
  • stack -- the canonical abstraction
  • List
  • Student,
  • etc.
classes and c structures
Classes and C structures
  • default access for class: private
  • default access for struct:public

This is the only difference between

a C++ class and a C++ structure.

classes
Classes
  • Example of a bad class declaration

class Student {

public:

float gpa;

char * name;

};

classes and structures
Classes and structures
  • Correct example of Class Declaration

class Student {

private:

float gpa;

char * name;

};

    • do we need the “private” designation?

How do I access the "private" data?

classes writing set and get functions
Classes: writing set and getfunctions

provide accessor and

modifier functions

class Student {

public:

void setGpa(float g) { gpa = g; }

void setName(char * n) {

name = new char[strlen(n)+1];

strcpy(name, n);

}

private:

float gpa;

char * name;

};

What's missing?

classes and objects
Classes and Objects
  • Declaration of a class variable (i.e. object)

Student s, t;

Student * v;

int i;

float x;

    • The syntax is identical to conventional variable declarations.

This one is on the stack.

This one will be on the heap.

classes9
Classes
  • Since class declarations will likely be used by many program modules, put them in a header file that can be included as required

#include “Student.h”

classes and objects10
Classes and Objects

function call

  • Access to class data members

s.setGpa(3.5);

s.setName(“Dana”);

v = new Student(4.0, “Fox”);

t = s;

  • The Student class also needs constructors

shallow copy?

classes constructors
Classes: constructors

class Student {

public:

Student(); //default

Student(char*, float); //conversion

Student(const Student&); //copy

friend ostream & operator<<(ostream &,

const Student &);

private:

char * name;

float gpa;

};

This is an example of an

improper class definition!

constructor parameters
Constructor parameters:
  • Default: no parameters
  • Conversion: parameters to make one
  • Copy: the parameter is the copy instance

Default is used with arrays of objects.

Copy is used with "pass by value"

constructors destructors
Constructors/destructors
  • Guarantee that data is initialized
  • allow classes to manage memory
    • constructors allocate: new
    • destructors deallocate: delete

Especially important for heap based memory

prefer initialization to assignment
Prefer initialization to assignment

class Student {

public:

Student(int a) : age(a), iq(age+100) {}

Student(int a) { age = a; iq = age + 100; }

private:

int age;

int iq;

};

prefer init to assign
Prefer init to assign
  • Initialization is more efficient for data members that are objects:
    • init: uses copy constructor
    • assign: uses default constructor and assignment
  • only way to pass a parameter to base class
passing param to base class
Passing param to base class

class Person {

public:

Person(int a) : age(a) {}

private:

int age;

};

class Student : public Person {

public:

Student(int age, float g) : Person(age), gpa(g) {}

private:

float gpa;

};

list members in init list in order that they are declared
List members in init list in order that they are declared

class members are initialized in the order of

their declaration in the class! What’s the value of iq?

class Student {

public:

Student(int a) : age(a), iq(age+100) {}

private:

int iq;

int age;

};

exercise to learn constructors
Exercise to learn constructors
  • Write 3 constructors and a destructor for Student class. Test it with:

void fun(Student stu) {}

int main() {

Student a, b(“Darth Maul”, 3.5), c = b;

Student * d = new Student(“Anakin”, 4.0);

cout << *d << endl;

fun(a);

return 0;

}

why is this a bad class definition at least 2 member functions missing
Why is this a bad class definition?at least 2 member functions missing

class Student {

public:

Student(); //default

Student(char*, float); //conversion

Student(const Student&); //copy

friend ostream & operator<<(ostream &,

const Student &);

private:

char * name;

float gpa;

};

This is an example of an

improper class definition!

q what output should we get
Q: what output should we get:

int main() {

Student x(“Count Dooku”), y(“Anakin”);

x = y;

y.setName(“Darth Maul”);

cout << x << endl;

}

Soln: needdeep copy: operator=

copying a class object
Copying a class object

Original

Object

Shallow

Copy

copying a class object22
Copying a class object

Original

Object

Deep

Copy

canonical orthodox class form j coplien
Canonical orthodox class form J. Coplien
  • Default constructor
  • copy constructor
  • destructor
  • assignment operator

operator<<

what functions does c silently write
What functions does C++silently write?

class Empty{};

class Empty {

public:

Empty();

Empty(const Empty &);

~Empty();

Empty& operator=(const Empty &);

Empty * operator&();

const Empty * operator&() const;

};

If you write this

You get this;

if needed!

how would you need them
How would you need them?

const Empty e1; // need default constructor, and

// destructor

Empty e2(e1); // copy constructor

e2 = e1; // assignment operator

Empty * pe2 = &e2; // address-of operator (non const)

const Empty *pe1 = &e1; // address-of operator (const)

what do the compiler generated functions look like
What do the compiler generated functions look like?

inline Empty::Empty() {}

inline Empty::~Empty() {}

inline Empty * Empty::operator&() { return this; }

inline const Empty * Empty::operator&() const {

return this;

}

The copy constructor and assignment operator simply

do a member wise copy, i.e., shallow. Note that the

default assignment induces a memory leak in Student!

note: destructor is NOT virtual

when do we need to write a copy constructor destructor assign operator
When do we need to write a copy constructor, destructor & assign operator?
  • Anytime the class has heap-based data members
  • all base classes should have a virtual destructor
  • Studies have shown that, if you don’t need copy/assign, the compiler generated functions run 10-20% faster than programmer generated ones.
how do we overload assignment
How do we overload assignment?

Student & operator=(const Student & stu) {

if (*this == stu) return * this;

delete [] name;

name = new char[strlen(stu.name)+1];

strcpy(name, stu.name);

gpa = stu.gpa;

return *this;

}

(1) Why the comparison on the first line?

(2) Could the first line be: if (this == &stu)?

(3) Why return *this? What does it enable?

(4) Why not return stu, rather than *this?

formula for overloaded assignment
Formula for overloaded assignment
  • Check for equality of lhs & rhs
  • delete storage for lhs
  • create new storage for lhs, that’s size of rhs
  • copy rhs “stuff” to lhs
  • return *this
an overloaded binary operator
an overloaded binary operator
  • can be written in infix form
    • a = b;
    • cout << stu;
  • or can be written in prefix form
    • a.operator=(b)
    • cout.operator<<(stu)

here it's more obvious

what "this" is

principle of least privilege
Principle of least privilege
  • Can reduce debugging and provide documentation by only allowing a function the least amount of privilege
  • can prevent a function from modifying a parameter
  • can prevent a member function from modifying data attributes
  • allow a function enough data access to accomplish its task – and no more!
explicitly disallow any implicit functions you don t want
Explicitly disallow any implicit functions you don’t want!
  • Suppose you want to write a class template array that behaves like C++ arrays, except that it does bounds check
  • C++ does not allow array assignment; e.g. int a[10], b[10]; a = b; //error

don’t define the

operator= to keep

member & friend

functions from

using it!

class Array {

private:

Array & operator=(const Array & );

};

overloading operators
Overloading operators
  • almost all operators can be overloaded
  • operators are binary or unary
  • have the same precedence as their compiler counterpart
  • can be members or friends, usually
  • overloaded output operator cannot be a member of any user defined class
overloading output operator as a friend function
overloading output operator:as a friend function

class Student {

public:

getName() { return name; }

getGpa() { return gpa; }

friend ostream & operator<<(ostream &, const Student &);

private:

char * name;

float gpa;

};

ostream & operator<<(ostream & out, const Student & s) {

out << s.getName() << “\t” << s.getGpa();

return out;

}

overloading output operator as stand alone function
Overloading output operator:as stand-alone function

class Student {

public:

getName() { return name; }

getGpa() { return gpa; }

private:

char * name;

float gpa;

};

ostream & operator<<(ostream & out, const Student & s) {

out << s.getName() << “\t” << s.getGpa();

return out;

}

What's wrong with this class definition?

put prototype in header file and body in implementation file
Put prototype in header file,and body in implementation file

class Student {

public:

getName() const { return name; }

getGpa() const { return gpa; }

private:

char * name;

float gpa;

};

ostream & operator<<(ostream &, const Student &);

ostream & operator<<(ostream & out, const Student & s) {

out << s.getName() << “\t” << s.getGpa();

return out;

}

header file

implementation file

exercise with classes
Exercise with classes:
  • Complete the definition of Student with all 3 constructors, overloaded assignment, overloaded output, and get and set
  • Write a main program that contains 2 functions:
    • a function to init the list with 3 Students
    • a function that prints the list
using students
Using students
  • In actual practice, we want to store lots of students
  • need an array of students

Student list[10];

Q: How many times does a constructor get called for list?

Q: which constructor?

what s missing
What’s missing:
  • Need an easier way to print a student
    • overload the output operator <<
    • operator<< must be a friend function; cannot be a member function cuz it’s already a member of class ostream
  • Need a class to manage the list of Students
friends
Friends
  • Can access private member functions and private data attributes!
  • Can be functions or classes
  • Might not always be best solution!
overloading the output operator
Overloading the output operator

Class Student {

public:

friend ostream & operator<<(ostream & out, const Student & student){

out << student.name;

return out;

}

};

slide42

Class StudentManager {

public:

StudentManager() : count(0) { }

void insert(const Student &);

friend ostream & operator<<(ostream &, const Student &);

private:

int count;

Student list[100];

};

42

42

slide43

Class StudentManager {

public:

StudentManager() : count(0) {}

void insert(const Student & student) {

list[count++] = student;

}

friend ostream & operator<<(ostream & out,

const Student & student) {

for (int i = 0; i < count; ++i) out << student[i] ;<< endl;

return out;

}

private:

int count;

Student list[100];

};

43

43

class exercise
Class exercise:
  • Complete the StudentManager Class;
  • rewrite main to use the List Class.
  • Write a new main program that allows the user to choose among commands:
    • insert student
    • delete student
    • print the list
    • find a student
    • exit
discussion of manager class
Discussion of Manager class:
  • Advantages:
    • encapsulates functionality into a single class
    • simplifies the main program
  • Disadvantages:
    • there is a limit (100) on number of Students
    • Student’ default constructor called 100 times!
suggested naming conventions
Suggested Naming Conventions
  • global constants: ALL CAPS!
  • local & global variables: ALL LOWER CASE, USE UNDERSCORE
  • Class names: BEGIN EACH WORD WITH UPPER CASE, NO UNDERSCORE
  • Class member functions: BEGIN LOWER CASE, then BEGIN EACH WORKD WITH UPPER CASE
  • Data members: SAME AS MEMBER FUNCTIONS
operator overloading adt for binary math
Operator Overloading:ADT for binary math
  • Would like variables of type binary to be like any other data type. Thus:
    • overload arithmetic operators
    • overload output to be binary
    • overload input to use decimal
  • How do we represent internally?
binary should look like int
Binary should “look like” int

#include “Binary.h”

main() {

int sum = 0;

Binary number1, number2 = 7;

number1 = 15;

cout << number1 + number2 << endl;

}

slide49

// This is file Binary.h

class Binary {

public:

Binary() : number(0) {}

Binary(int n) : number(n) {}

Binary(const Binary & bin);

Binary operator+(const Binary &);

Binary& operator++();

Binary& operator=(const Binary &);

friend ostream & operator<<(ostream &, const Binary &);

private:

int number;

};

Where's the destructor?

49

49

slide50

#include “Binary.h” // this is file Binary.cpp

Binary Binary::operator+(const Binary & rhs) {

Binary temp(number+rhs.number);

return temp;

}

Binary& operator++() {

++number;

return *this;

}

50

50

slide51

// this is a global function; s/b in Binary.cpp

ostream & operator<<(ostream & out, const Binary & bin) {

stack<int> stk;

int number = bin.number;

while (number) {

stk.push( number % 2 );

number /= 2;

}

while ( !stk.empty() ) {

out << stk.top();

stk.pop();

}

return out;

}

51

51

exercise for binary type
Exercise for Binary type:
  • Complete the class definition for Binary
  • construct a main program that uses Binary
  • Discuss return value transmission mode
    • operator=
    • operator++
    • operator+ (postfix, prefix)
  • Discuss merits of friend vs member functions for +, ++, output, etc.
discussion of binary class
Discussion of Binary class
  • Compilation can be made simpler by using a makefile
  • makefile automatically compiles and links program modules
  • makefiles are mysterious
makefile makefile
makefile/Makefile
  • Consist of definitions,
  • Followed by sequences of 2 line commands.
    • Begins with id:, followed by dependencies of id.
    • Second line is the rule to make id; this line MUST be preceded by a tab
  • To use the make file type: make {<id>}
slide55

CCC=g++

FLAGS=-Wall

main: main.o Binary.o

$(CCC) $(FLAGS) -o main main.o Binary.o

main.o: main.cpp Binary.h

$(CCC) $(FLAGS) -c main.cpp

Binary.o: Binary.cpp Binary.h

$(CCC) $(FLAGS) -c Binary.cpp

clean:

rm -f main *.o core

55

55

discussion of makefile
Discussion of makefile
  • $(CCC) permits us to easily switch to another compiler; e.g. CC
  • make clean will ‘clean’ the directory of large files
  • -o option creates an executable
  • -c option creates .o file
c strings are no fun
C-strings are no fun:
  • Programmer must manage memory
  • comparison is awkward
  • concatenation is non-standard
    • strcat(a, b), instead of:
    • a + b
  • No substring facilities
solution write our own string class what do we need
Solution: write our own String classWhat do we need:
  • Constructors
    • default
    • conversion
    • copy
  • overloaded operators
    • output
    • concatenation
dynamic storage
Dynamic storage
  • Need pointers
  • “never” run out of room ;-)
  • must allocate storage: new
  • must also deallocate storage: delete
  • failure to deallocate storage: memory leak
  • constructors/destructors were designed to facilitate memory management
slide60

// This class definition of String s/b in file: String.h

class String {

public:

String();

String(char *);

String(const String &);

String operator+(const String &);

int len() const ;

friend ostream & operator<<(ostream &, const String &);

private:

char * buf;

};

60

60

slide61

// This class definition of String s/b in file: String.h

class String {

public:

String(int n = 0) : buf(new char[n+1]) { buf[0] = ‘\0’; }

String(char * s) : buf(new char[strlen(s)+1]) { strcpy(buf, s); }

String(const String &);

~String() { delete [] buf; }

char & operator[](int i) { return buf[i]; }

String operator+(const String &);

int len() const { return strlen(buf); }

friend ostream & operator<<(ostream &, const String &);

private:

char * buf;

};

61

61

slide62

// This is file String.cpp

#include “String.h”

ostream & operator<<(ostream & out, const String & s) {

out << s.buf;

return out;

}

String String::operator+(const String & rhs) {

String temp( strlen(buf)+strlen(rhs.buf) );

strcpy(temp.buf, buf);

strcat(temp.buf, rhs.buf);

return temp;

}

62

62

we need operator
We need operator==
  • Discuss the merits of the following comparison function:

bool String::operator==(const String & rhs) {

return (*this == rhs);

}

string exercise
String exercise:
  • Discuss ‘what’s missing’ from String spec
  • Complete the class definition and implementation; write copy constructor
  • Write a main program that uses Strings.
  • Write a makefile
  • Thoroughly test the class
  • Is there one in the standard C++ library?
string exercise65
String exercise:
  • Add operator= to String
  • Q: when are constructors called?
  • Q: when is assignment called?
  • Q: which is better: initialization or assignment?
  • Consider main.cpp, String.h and String.cpp

orthodox canonical class form

slide66

#include “String.h”

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

if (*this == rhs) return *this;

delete [] buf;

buf = new char[strlen(rhs.buf) + 1];

strcpy(buf, rhs.buf);

return *this;

}

66

66

discussion of string operator
Discussion of String::operator=
  • Note the return transmission mode. Why?
  • what happens if we do not delete buf?
  • Why do we need +1 when we newbuf ?
  • What does return *this mean?
  • Discuss the following 3 options:
    • if (*this == rhs) return *this;
    • if (this == &rhs) return *this;
    • if (strcmp(buf, rhs.buf) ==0) return *this;
slide68

#include “String.h”

int main() {

String a, b(“hello”),

c(a), d = “world”;

}

What constructors are called?

68

68

slide69

// Note that it’s more efficient if constructors

// use initialization rather than assignment.

// To see: place cout in constructors for String!

class Test {

public:

Test(char *n) : name(n) {} // initialization

Test(char *n) { name = n; } // assignment

private:

String name;

};

main() {

Test t(“surprise”);

}

69

69

making string s useful
Making Strings useful:
  • Sometimes we want to ‘run through’ a string; i.e. iterate through the string.
  • For example, if we read a line of text from a file, we might want to access each word on the line.
  • Can write a special class called an iterator
iterator class
Iterator class
  • Allows user to ‘look at’ each item in the data structure
  • can be forward or backward
  • can have more than one iterator on a given data structure
iterator
iterator
  • For a linked list: would return each item in the list, starting with the first an proceeding through the list;
  • for a string: might return each word in the list, or it might return each character
  • for a tree: would return each item in the tree, in some order (preorder, depth first, etc.)
slide73

// partial specification for iterator over String

class StringIterator {

public:

StringIterator(const String & s, char d = ‘ ‘)

: str(s), index(0) , delim(d) {}

void operator++();

String operator() () const;

bool atEnd() const { return index == str.len(); }

private:

String str;

unsigned int index;

char delim;

};

73

73

stringiterator spec discussion
StringIterator spec discussion
  • Constructor must init data members in the order that they are listed in the declaration
  • default delimiter is a blank
  • overloaded parens looks odd
  • note that str.len() is one past the end!
  • we could overload operator<< for debugging
slide75

// implementation of operator++

#include “StringIterator.h”

void StringIterator::operator++() {

while (index < str.len() && str[index] != delim) ++index;

while (index < str.len() && str[index] == delim) ++index;

}

75

75

slide76

// implementation of operator()

String StringIterator::operator() () const {

char buf[80];

int temp_index = index, i = 0;

while (temp_index < str.len() && str[temp_index] != delim)

buf[i++] = str[temp_index++];

buf[i] = ‘\0’;

return String(buf);

}

might be better to overload

operator() *

76

76

stringiterator exercises
StringIterator exercises:
  • Complete the specification and implementation
  • overload operator<< for debugging
  • thoroughly test your ADT
  • extend StringIterator to accept a set of delimiters
  • what happens if you initialize the data members in different order than they are declared?
stack a common data structure
Stack: a common data structure
  • Public operations:
    • push
    • pop
    • test empty
    • possibly test full
  • private data representation

The canonical abstraction

78

slide79

class IntStack {

public:

IntStack() : count(EMPTY) {}

void push(int n) { items[++count] = n; }

void pop() { --count; }

int top() const { return items[count]; }

bool isEmpty() const { return count == EMPTY; }

bool isFull() const { return count == 99; }

private:

enum {EMPTY = -1};

int items[100];

int count;

};

79

79

stack exercise
Stack exercise:
  • Implement and test Stack class
  • Discuss alternatives to items[100]
  • modify IntStack so that it accepts a parameter describing the size of items
  • Discuss drawbacks of IntStack
  • What are solutions to drawbacks?
template classes
Template classes
  • Functions accept variables as parameters
  • template classes accept types as parameters
  • functions can also use templates
slide82

template <class T>

class Stack {

public:

Stack() : count(EMPTY) {}

void push(const T & n) { items[++count] = n; }

void pop() { --count; }

const T top() const { return items[count]; }

bool isEmpty() const { return count == EMPTY; }

bool isFull() const { return count == 99; }

private:

enum {EMPTY = -1};

T items[100];

int count;

};

82

82

discussion of template stack
Discussion of template stack
  • Note the change in parameter transmission from IntStack to Stack<T>
  • Note that top() passes return by value; can pass-by-value return be avoided?
  • Can arrays, in C++, be dimensioned dynamically?
  • What happens if user pops from empty stack?
exceptions
Exceptions
  • Useful for handling error conditions.
  • Also useful for exceptional cases, such as eof, end-of-line, etc.
  • keywords: try, catch, throw
how to use exceptions
How to use exceptions
  • Each try block has corresponding catch block(s)
  • calls to functions that may throw an exception are placed in a try block.
  • The called function, when faced with exceptional condition, performs a throw
  • the exception is thrown back, through the call chain, to matching catch, or
  • program bombs!
slide86

// give the output for the program below:

void fun(int number) {

if (number % 2 == 0) throw “error”;

cout << “This is fun” << endl;

}

main() {

try {

fun(2);

fun(3);

}

catch (char * msg) {

cout << msg << endl;

return 1;

}

}

86

slide87

// give the output for the program below:

void fun(int number) {

if (number % 2 == 0) throw “error”;

cout << “This is fun” << endl;

}

main() {

int n = 2;

while (n) {

try { fun(n--); }

catch (char * msg) {

cout << msg << endl;

}

}

}

87

slide88

class Clean {

public:

Clean() { cout << “constructing Clean” << endl; }

~Clean() { cout << “destroying Clean” << endl; }

};

void fun() {

Clean c;

throw “error”;

}

main() {

try { fun(); }

catch(char * msg) { cout << msg << endl; }

}

what's the output?

what's the point?

88

stack exercise89
Stack exercise
  • Add exception handling to Stack class
  • write a main program with try/catch block that uses Stack
dynamic storage90
Dynamic storage
  • Need pointers
  • “never” run out of room ;-)
  • must allocate storage: new
  • must also deallocate storage: delete
  • failure to deallocate storage: memory leak
  • constructors/destructors were designed to facilitate memory management
linked list
Linked list
  • Dynamic memory used to store data (usually in a node!)
  • node usually stores data and pointer to next node (at least)
  • can be singly linked, doubly linked, circularly linked
  • can have dummy header node and/or dummy footer node
singly linked list
Singly linked list

head

node

node

node

92

slide93

// partial specification & implementation for Node class

class Node {

public:

friend class List;

Node() : data(0), next(NULL) {}

Node(int d, Node * n) : data(d), next(n) {}

int getData() const;

void setData(int d) ;

friend ostream & operator<<(ostream &,

const Node &);

private:

int data;

Node * next;

};

93

93

slide94

// partial specification & implementation for Node class

class Node {

public:

friend class List;

Node(int d = 0, Node * n = NULL) : data(d), next(n) {}

int getData() const { return data; }

void setData(int d) { data = d; }

friend ostream & operator<<(ostream & out,

const Node & node) {

out << node.data; return out;

}

private:

int data;

Node * next;

};

94

94

slide95

#include “Node.h”

class List{

public:

List() : head(NULL), current(NULL) {}

void insert(int data) { head = new Node(data, head); }

void delete() {

Node * temp = head; head = temp->next; delete temp;

}

Node * getFront() { current = head; return current; }

Node * getNext() { current=current->next; return current:}

friend ostream & operator<<(ostream &, const List &);

private:

Node * head;

Node * current;

};

95

95

discussion of list class
Discussion of List class
  • insert actually inserts at the front
  • getFront, getNext and current allow us to iterate through the list. Is there a better way?
  • Why is List a friend of Node?
  • Can we construct Node and List so that friendship is not required?
  • Note that deleting an arbitrary element is tricky. Would a doubly linked list simplify?
  • Should List be templated?
list class exercise
List class exercise
  • Complete specification & implementation, adding insertAtRear, insertAtFront, insert, deleteFront, deleteRear, deleteNth, ...
  • Write a main program that uses List and test
  • Re-write Node and List so that friendship is not required.
  • Push the envelope: template List
  • Write an iterator class for List
list exercise
List exercise
  • Find a solution to the Josephus problem for inputs n and m
  • describe a solution, using IntList, to the problem of arbitrary precision arithmetic. Compare the speed of your program with bc on unix.
doubly linked list
Doubly linked list
  • Easier to delete an arbitrary element
  • more overhead to implement
  • more storage
  • sometimes use a dummy header node to facilitate inserting into an empty list and deleting from a list of size 1.
  • Can use a pointer to the front and rear, facilitating insertion at either end.
doubly linked list100
Doubly linked list

dummy

node

node

front

rear

node

prev

number

next

slide101

#include <iostream.h>

class Node {

public:

friend class List;

friend class ListIterator;

Node(int i = 0, Node * n = NULL, Node * p = NULL)

: number(i), next(n), prev(p) {}

friend ostream & operator<<(ostream &, const Node &);

private:

int number;

Node * next;

Node * prev;

}

101

slide102

#include “Node.h”

class List {

public:

friend class ListIterator;

List() { rear = front = new Node; }

void insertAtFront(int n);

void insertAtRear(int n);

bool empty const { return front == rear; }

int size() const;

friend ostream & operator<<(ostream &, const List &);

private:

Node * front;

Node * rear;

}

102

slide103

class ListIterator {

public:

ListIterator (const List & list)

: front(list.front), current(list.front->next) {}

void init() { current = front; }

void operator++() { current = current->next; }

Node * operator() () const { return current; }

bool more() const { return current != NULL; }

private:

Node * front;

Node * current;

};

103

doubly linked list exercises
Doubly linked list exercises
  • Complete the spec and implementation
  • test the list