Topics
1. Member Access
(Ref. Lippman 13.1.3, 17.2, 18.3)
Types of Access Privilege
TYPE OF MEMBER | ACCESSIBLE IN CLASS DEFINITION | ACCESSIBLE BY OBJECTS |
---|---|---|
private | yes | no |
protected | yes | no |
public | yes | yes |
Member Access Under Inheritance
INHERITANCE ACCESS SPECIFIER | TYPE OF MEMBER IN BASE CLASS | ACCESS LEVEL IN FIRST DERIVED CLASS | ACCESSIBLE BY FIRST DERIVED CLASS DEFINITION | ACCESSIBLE BY FIRST DERIVED CLASS OBJECTS |
---|---|---|---|---|
private |
private protected public |
- private private |
no yes yes |
no no no |
protected |
private protected public |
- protected protected |
no yes yes |
no no no |
public |
private protected public |
- protected public |
no yes yes |
no no yes |
Key Points
- Private members are only accessible within the class that they are declared. They are not accessible by derived class definitions.
- Protected members are not accessible by objects. They are always accessible by a first level derived class.
- The inheritance access specifier places an upper limit on the access level of inherited members in the derived class.
2. A Linked List Class
Class Declaration
list.h
#ifndef _LIST_H_
#define _LIST_H_
#include <iostream.h>
#ifndef TRUE
#define TRUE 1
#endif // TRUE
#ifndef FALSE
#define FALSE 0
#endif // FALSE
// Generic list element. ListElement is an abstract class which will be
// subclassed by users of the List class in order to create different types
// of list elements.
class ListElement {
private:
ListElement *mpNext; // Pointer to next element in the list.
public:
ListElement() {mpNext = NULL;}
virtual ~ListElement() {}
// A pure virtual method which returns some measure of the element’s
// importance for purposes of ordering the list. The implementation
// will be provided by individual subclasses. The list will be ordered
// from most significant (at the head) to least significant.
virtual float ElementValue() = 0;
// A pure virtual method which prints out the contents of the list element.
// Implementation will be provided by individual subclasses.
virtual void print() = 0;
// Grant special access privilege to class list.
friend class List;
// An operator<< which prints out a list.
friend ostream& operator<<(ostream &os, const List& list);
};
// A linked list class.
class List {
private:
ListElement *mpHead; // Pointer to the first element in the list.
public:
// Create an empty list.
List();
// Destroy the list, including all of its elements.
~List();
// Add an element to the list. Returns TRUE if successful.
int AddElement(ListElement *pElement);
// Remove an element from the list. Returns TRUE if successful.
int RemoveElement(ListElement *pElement);
// Return a pointer to the largest element. Does not remove it from the list.
ListElement *GetLargest();
// Return a pointer to the smallest element. Does not remove it from the list.
ListElement *GetSmallest();
// An operator<< which prints out the entire list.
friend ostream& operator<<(ostream &os, const List& list);
};
#endif // _LIST_H_
Class Definition
list.C
#include “list.h”
// Create an empty list.
List::List() {
mpHead = NULL;
}
// Destroy the list, including all of its elements.
List::~List() {
ListElement *pCurrent, *pNext;
for (pCurrent = mpHead; pCurrent ! = NULL; pCurrent = pNext) {
pNext = pCurrent->mpNext;
delete pCurrent;
}
}
// Add an element to the list. Returns TRUE if successful.
int List::AddElement(ListElement *pElement) {
ListElement *pCurrent, *pPrevious;
float fValue = pElement->ElementValue();
pPrevious = mpHead;
for (pCurrent = mpHead; pCurrent != NULL; pCurrent = pCurrent->mpNext) {
if (fValue > pCurrent->ElementValue()) {
// Insert the new element before the current element.
pElement->mpNext = pCurrent;
if (pCurrent == mpHead)
mpHead = pElement;
else
pPrevious->mpNext = pElement;
return TRUE;
}
pPrevious = pCurrent;
}
// We have reached the end of the list.
if (mpHead == NULL)
mpHead = pElement;
else
pPrevious->mpNext = pElement;
pElement->mpNext = NULL;
return TRUE;
}
// Remove an element from the list. Returns TRUE if successful.
int List::RemoveElement(ListElement *pElement) {
ListElement *pCurrent, *pPrevious;
pPrevious = mpHead;
for (pCurrent = mpHead; pCurrent != NULL; pCurrent = pCurrent->mpNext) {
if (pCurrent == pElement) {
if (pCurrent == mpHead)
mpHead = pCurrent->mpNext;
else
pPrevious->mpNext = pCurrent->mpNext;
delete pCurrent;
return TRUE;
}
pPrevious = pCurrent;
}
// The given element was not found in the list.
return FALSE;
}
// Return a pointer to the largest element. Does not remove it from the list.
ListElement *List::GetLargest() {
return mpHead;
}
// Return a pointer to the smallest element. Does not remove it from the list.
ListElement *List::GetSmallest() {
ListElement *pCurrent, *pPrevious;
pPrevious = mpHead;
for (pCurrent = mpHead; pCurrent != NULL; pCurrent = pCurrent->mpNext) {
pPrevious = pCurrent;
}
return pPrevious;
}
// An operator<< which prints out the entire list.
ostream& operator<<(ostream &os, const List& list) {
ListElement *pCurrent;
for (pCurrent = list.mpHead; pCurrent ! = NULL;
pCurrent = pCurrent->mpNext) {
// Print out the contents of the current list element. Since the
// print method is declared to be virtual in the ListElement class,
// the actual print method to be used will be determined at run time.
pCurrent->print();
}
}
Using the Linked List Class
shapes.h
// Some shapes that we may wish to store in a linked list.
// We will order the shape objects according to their areas.
#ifndef _SHAPE_H_
#define _SHAPE_H_
#define PI 3.14159
#include “list.h”
class Triangle : public ListElement {
private:
float mfBase, mfHeight;
public:
// Unless we provide an explicit base class initializer, the base
// class will be initialized using its default constructor.
Triangle() {mfBase = mfHeight = 0.0;}
Triangle(float fBase, float fHeight) {mfBase = fBase; mfHeight = fHeight;}
~Triangle() {}
float ElementValue() {return (mfBase * mfHeight / 2);}
void print() {cout << “Triangle: area = " << ElementValue() << endl;}
};
class Rectangle : public ListElement {
private:
float mfBase, mfHeight;
public:
// Unless we provide an explicit base class initializer, the base
// class will be initialized using its default constructor.
Rectangle() {mfBase = mfHeight = 0.0;}
Rectangle(float fBase, float fHeight) {mfBase = fBase; mfHeight = fHeight;}
~Rectangle() {}
float ElementValue() {return (mfBase * mfHeight);}
void print() {cout << “Rectangle: area = " << ElementValue() << endl;}
};
class Circle : public ListElement {
private:
float mfRadius;
public:
// Unless we provide an explicit base class initializer, the base
// class will be initialized using its default constructor.
Circle() {mfRadius = 0.0;}
Circle(float fRadius) {mfRadius = fRadius;}
~Circle() {}
float ElementValue() {return (PI * mfRadius * mfRadius);}
void print() {cout << “Circle: area = " << ElementValue() << endl;}
};
#endif // _SHAPE_H_
list_test.C
#include “shapes.h”
main() {
List list;
ListElement *p;
p = new Triangle(4, 3);
list.AddElement(p);
p = new Rectangle(2, 1);
list.AddElement(p);
p = new Circle(2);
list.AddElement(p);
p = new Triangle(3, 2);
list.AddElement(p);
p = new Circle(1);
list.AddElement(p);
cout << list << endl;
list.RemoveElement(list.GetLargest());
cout << list << endl;
list.RemoveElement(list.GetSmallest());
cout << list << endl;
}