COMP2004
Programming Practice
2002 Summer School


Kevin Pulo
School of Information Technologies
University of Sydney


(page 1)


Operator Overloading




(page 2)


Output Operator Overloading


class List {
// ...
};

ostream& operator<<(ostream &os,
const List &list) {
// ...
}


(page 3)


Output Operator Overloading


ostream& operator<<(ostream &os,
const List &list) {
Node *c = list.head;
if (c) {
os << c.number;
c = c->next;
}
for (; c; c = c->next)
os << ' ' << c.number;
return os;
}


(page 4)


Friend functions


class List {
// ...
friend ostream& operator<<
(ostream &os, const List &list);
};


(page 5)


Better Design




(page 6)


Operator<<


ostream& operator<<(ostream &os,
const List &list) {
List::ConstIterator b = list.begin(),
e = list.end();
if (b != e) {
os << *b;
++b;
}
for (; b != e; ++b)
os << ' ' << *b;
return os;
}


(page 7)


Converting types


List::List(const std::string &s);


(page 8)


Conversion operators


List::operator bool() const {
return head;
}


(page 9)


Conversion operator example


List::operator bool() const {
return head;
}
int main() {
List l;
if (l)
cout << "List has stuff" << endl;
else
cout << "List is empty" << endl;
}


(page 10)


Inheritance




(page 11)


class Alarm {
public:
void turn_on() {
std::cout << "Alarm on\n";
}
};


class BuzzerAlarm : public Alarm {
public:
void turn_on() {
std::cout << "Buzzer on\n";
}
};

(page 12)


What Is Output?


void activate(Alarm a) {
a.turn_on();
}

int main() {
BuzzerAlarm b;
activate(b);
}


(page 13)


A Problem




(page 14)


First Attempt At Fix


void activate(Alarm &a) {
a.turn_on();
}

void activate(Alarm *a) {
a->turn_on();
}


(page 15)


More Problems




(page 16)


Fixed Alarm class


class Alarm {
public:
virtual void turn_on() {
std::cout << "Alarm on\n";
}
};


(page 17)


Virtual




(page 18)


Accessibility and Inheritance




(page 19)


Accessibility Example


class Base {
public: int i;
protected: int j;
private: int k;
};
class Child : public Base {
void test() {
i = 1; // legal
j = 1; // legal
k = 1; // ERROR
}
};


(page 20)


Constructors and Inheritance




(page 21)


Constructors Example


class Person {
public:
Person(const std::string &name);
};


class Student : public Person {
public:
Student(const std::string &name, const
std::string &sid) : Person(name) {
// ...
}
};


(page 22)


Destructors and Inheritance




(page 23)


Abstract Classes




(page 24)


Abstract Example


class Alarm {
public:
virtual void turn_on() = 0;
virtual void turn_off() = 0;
virtual bool is_on() = 0;
virtual ~Alarm() { };
};


(page 25)


Multiple Inheritance




(page 26)


Non-public Inheritance


class B : private A

class B : protected A


(page 27)


Non-public Inheritance Uses


class A { };
class B : private A { };
B b;
A *a = &b;


(page 28)


Namespaces




(page 29)


Namespace Example


namespace a {
std::string func() { return "a func\n"; }
}
namespace b {
std::string func() { return "b func\n"; }
}
std::string func() { return "func\n"; }
int main() {
std::cout << a::func() << std::endl;
std::cout << b::func() << std::endl;
std::cout << func() << std::endl;
}


(page 30)


Using Namespaces



namespace A { int fred = 10; }
int fred = 20;
int main() {
std::cout << fred << std::endl;
using A::fred;
std::cout << fred << std::endl;
std::cout << A::fred << std::endl;
}


(page 31)


Using Namespaces II


namespace A {
int fred = 10;
double bill = 10.0;
}
int main() {
using namespace A;
std::cout << fred << ' ' << bill;
std::cout << std::endl;
}


(page 32)


Unnamed Namespaces


namespace {
int number;
void function() { ... }
}
namespace ??? { ... }
using namespace ???;


(page 33)


Namespace Aliases




(page 34)


Alias Example


namespace A_Name_Which_Is_Long {
int foo = 42;
}

namespace short =
A_Name_Which_Is_Long;

int main() {
std::cout << short::foo << std::endl;
}



(page 35)