11. Нова реализация на свързани списъци
Предефиниране
на оператори (операции)
** Даване на ново значение на операция се нарича предефиниране (operator
overloading).
** Операциите се предефинират с аргумети - обекти от даден клас.
** Предефиниране на унарни и бинарни операции
** Използване във верига
// overload.cpp
#include <iostream>
using namespace std;
#include "ccc_time.cpp"
long operator-(Time a, Time b)
{ return a.seconds_from(b);
}
Time operator+(Time a, long sec)
{ Time r = a;
r.add_seconds(sec);
return r; }
bool operator==(Time a, Time b)
{ return a.seconds_from(b) == 0;
}
bool operator!=(Time a, Time b)
{ return a.seconds_from(b) != 0;
}
ostream& operator<<(ostream&
out, Time& a)
{ out << a.get_hours() <<
":";
if (a.get_minutes() <
10) out << "0";
out << a.get_minutes()
<< ":";
if (a.get_seconds() <
10) out << "0";
out << a.get_seconds();
return out;
}
int main()
{ Time now;
cout << "Now it is
" << now << "\n";
Time later = now + 1000;
cout << "A thousand
seconds later it is " << later << "\n";
Time now2;
if (now == now2)
cout <<
"It still is " << now2 << "\n";
if (now != now2)
cout <<
"It is already " << now2 << "\n";
cout << "Another "
<< later - now2 << " seconds until "
<< later << "\n";
return 0;
}
Префиксна и постфиксна форма на операцията ++
operator++(Time &a)
operator++(Time &a, int dummy)
Предефиниране на операции като член-функции на клас
bool operator!=(Iterator a, Iterator b)
// външна за класа функция
bool Iterator::operator!=(Iterator b)
// член-функция
string Iterator::operator*() const
{ assert(position != NULL);
return position->data;
}
void Iterator::operator++(int dummy)
{ assert(position != NULL);
position = position->next;
}
void Iterator::operator--(int dummy)
{ if (position == NULL) position
= last;
else
position = position->previous;
assert(position != NULL);
}
bool Iterator::operator!=(Iterator b) const
{ return position != b.position;
}
bool Iterator::operator==(Iterator b) const
{ return position == b.position;
}
Шаблони
// list3.cpp
#include <string>
#include <iostream>
#include <cassert>
using namespace std;
template<typename T>
class List;
template<typename T>
class Iterator;
template<typename T>
class Link {
public:
Link(T s);
private:
T data;
Link<T>* previous;
Link<T>* next;
friend class List<T>;
friend class Iterator<T>;
};
template<typename T>
class List {
public:
List();
void push_back(T s);
void insert(Iterator<T>
iter, T s);
void erase(Iterator<T>
iter);
Iterator<T> begin();
Iterator<T> end();
private:
Link<T>* first;
Link<T>* last;
};
template<typename T>
class Iterator {
public:
Iterator();
T operator*() const;
void operator++(int dummy);
void operator--(int dummy);
bool operator!=(Iterator<T>
b) const;
private:
Link<T>* position;
Link<T>* last;
friend class List<T>;
};
template<typename T>
Link<T>::Link(T s)
{ data = s;
previous = NULL;
next = NULL;
}
template<typename T>
List<T>::List()
{ first = NULL; last
= NULL; }
template<typename T>
void List<T>::push_back(T s)
{ Link<T>* newlink = new Link<T>(s);
if (last == NULL)
/* list is empty */
{ first = newlink;
last = newlink; }
else
{ newlink->previous
= last;
last->next
= newlink;
last =
newlink;
}
}
template<typename T>
void List<T>::insert(Iterator<T>
iter, T s)
{
if (iter.position == NULL)
{ push_back(s);
return; }
Link<T>* after = iter.position;
Link<T>* before = after->previous;
Link<T>* newlink = new
Link<T>(s);
newlink->previous = before;
newlink->next = after;
after->previous = newlink;
if (before == NULL) /* insert
at
beginning */
first =
newlink;
else
before->next
= newlink;
}
template<typename T>
void List<T>::erase(Iterator<T>
iter)
{
assert(iter.position != NULL);
Link<T>* remove = iter.position;
Link<T>* before = remove->previous;
Link<T>* after = remove->next;
if (remove == first)
first =
after;
else
before->next
= after;
if (remove == last)
last =
before;
else
after->previous
= before;
iter.position = after;
delete remove;
}
template<typename T>
Iterator<T> List<T>::begin()
{
Iterator<T> iter;
iter.position = first;
iter.last = last;
return iter;
}
template<typename T>
Iterator<T> List<T>::end()
{
Iterator<T> iter;
iter.position = NULL;
iter.last = last;
return iter;
}
template<typename T>
Iterator<T>::Iterator()
{ position = NULL;
last = NULL;
}
template<typename T>
T Iterator<T>::operator*() const
{
assert(position != NULL);
return position->data;
}
template<typename T>
void Iterator<T>::operator++(int dummy)
{
assert(position != NULL);
position = position->next;
}
template<typename T>
void Iterator<T>::operator--(int dummy)
{
if (position == NULL)
position = last;
else
position = position->previous;
assert(position != NULL);
}
template<typename T>
bool Iterator<T>::operator!=(Iterator<T>
b) const
{ return position != b.position;
}
int main()
{ List<string> staff;
staff.push_back("Cracker,
Carl");
staff.push_back("Hacker,
Harry");
staff.push_back("Lam, Larry");
staff.push_back("Sandman,
Susan");
/* add a value in fourth place */
Iterator<string> pos;
pos = staff.begin();
pos++;
pos++;
pos++;
staff.insert(pos, "Reindeer, Rudolf");
/* remove the value in second place */
pos = staff.begin();
pos++;
staff.erase(pos);
/* print all values */
for (pos = staff.begin();
pos != staff.end(); pos++)
cout <<
*pos << "\n";
return 0;
}