Бьерн Страуструп. Язык программирования С++ Второе дополненное издание



Pdf көрінісі
бет41/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   37   38   39   40   41   42   43   44   ...   256
1.4.5 Преобразования типов 
Определяемые пользователем преобразования типа, например, такие, как преобразование числа с 
плавающей точкой в комплексное, которое необходимо для конструктора complex(double), оказались 
очень полезными в С++. Программист может задавать эти преобразования явно, а может полагаться на 
транслятор, который выполняет их неявно в том случае, когда они необходимы и однозначны: 
complex a = complex ( 1 ); 
complex b = 1; 
// 
неявно: 1 -> complex ( 1 ) 
a = b + complex ( 2 ); 
a = b + 2;
// 
неявно: 2 -> complex ( 2) 


Бьерн Страуструп.
Язык программирования С++ 
 
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 ); 

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()) полностью огражден от деталей 
их реализации. Платой за подобную гибкость является то, что все операции над стеками должны быть 
виртуальными функциями. 


Достарыңызбен бөлісу:
1   ...   37   38   39   40   41   42   43   44   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет