Бьерн Страуструп.
Язык программирования С++
39
Преобразования типов нужны в С++ потому, что арифметические операции со смешанными типами
являются
нормой для языков, используемых в числовых задачах. Кроме того, большая часть
пользовательских типов, используемых для "вычислений" (например, матрицы, строки, машинные
адреса) допускает естественное преобразование в другие типы (или из других типов).
Преобразования типов способствуют более естественной записи программы:
complex a = 2;
complex b = a + 2; //
это означает: operator + ( a, complex ( 2 ))
b = 2 + a; //
это означает: operator + ( complex ( 2 ), a )
В обоих случаях для выполнения операции "+" нужна
только одна функция, а ее параметры
единообразно трактуются системой типов языка. Более того, класс complex описывается так, что для
естественного и беспрепятственного обобщения
понятия числа нет необходимости что-то изменять для
целых чисел.
1.4.6 Множественные реализации
Основные средства, поддерживающие объектно-ориентированное программирование, а именно:
производные классы и виртуальные функции,- можно использовать и
для поддержки абстракции
данных, если допустить несколько реализаций одного типа. Вернемся к примеру со стеком:
template < class T >
class stack
{
public:
virtual void push ( T ) = 0;
// чистая виртуальная функция
virtual T pop () = 0;
// чистая виртуальная функция
};
Обозначение =0 показывает, что для виртуальной функции не требуется никакого определения, а класс
stack является абстрактным, т.е. он может использоваться только как базовый класс. Поэтому стеки
можно использовать, но не создавать:
class cat { /* ... */ };
stack < cat > s; // ошибка: стек - абстрактный класс
void some_function ( stack
& s, cat kitty ) //
нормально
{
s.push ( kitty );
cat c2 = s.pop ();
//
...
}
Поскольку интерфейс стека ничего не сообщает о его представлении, от пользователей стека
полностью скрыты детали его реализации.
Можно предложить несколько различных реализаций стека. Например, стек может быть массивом:
template < class T >
class astack : public stack < T >
{
// истинное представление объекта типа стек
// в данном случае - это массив
//
...
public:
astack ( int size );
~astack
();
void push ( T );
T
pop
();
};
Можно реализовать стек как связанный список:
Бьерн Страуструп.
Язык программирования С++
40
template < class T >
class lstack : public stack < T >
{
//
...
};
Теперь можно создавать и использовать стеки:
void g ()
{
lstack < cat > s1 ( 100 );
astack < cat > s2 ( 100 );
cat
Ginger;
cat
Snowball;
some_function ( s1, Ginger );
some_function ( s2, Snowball );
}
О том, как представлять
стеки разных видов, должен беспокоиться только тот, кто их создает (т.е.
функция g()), а пользователь стека (т.е. автор функции some_function()) полностью огражден от деталей
их реализации. Платой за подобную гибкость является то, что все операции над стеками должны быть
виртуальными функциями.
Достарыңызбен бөлісу: