int iPrivateValue;
};
Еще одно различие между структурами и классами проявляется в разграничении доступа к элементам базового класса (см. раздел “Разграничение доступа к элементам базового класса”). Если вы наследуете новый класс от базового класса и не указываете спецификатор доступа, по умолчанию используется спецификатор private. Когда же вы наследуете от базового класса структуру, по умолчанию используется спецификатор public.
Шаблоны
Языки программирования С и Си++ обеспечивают строгую проверку типов данных. Некоторые языки не обеспечивают такой проверки и она полностью ложится на плечи программиста. Например в языке PL1 вы можете сравнивать значение строковой и числовой переменных. Это не будет ошибкой с точки зрения компилятора. Если вы случайно допустите ошибку, то обнаружить ее будет достаточно сложно.
Однако строгая типизация, присущая некоторым языкам, не всегда удобна. Если вам надо выполнять одинаковые вычисления над переменными различных типов, придется создавать две фактически одинаковые функции, которые оперируют с различными типами данных.
Аналогичная ситуация возникает, если вам надо создать класс, для работы с различными типами данных. Допустим вам надо создать список из элементов. Удобнее всего это сделать при помощи классов. Но если вам надо, чтобы в качестве элементов списка фигурировали различные типы данных, то вам наверняка придется написать несколько одинаковых классов, различающихся только типом элементов.
Естественно такая ситуация усложняет работу программиста, увеличивают объем исходных текстов программы, и наконец просто может стать причиной ошибок и несоответствий. Так, если в вашей программе содержится несколько функций или классов, отличающихся только типом данных, которыми они оперируют, то когда вы вносите исправления в одну функцию, надо будет точно также исправлять и все остальные.
Чтобы облегчить программисту работу, в стандарт языка Си++ было включено понятие шаблона. В Visual C++ шаблоны реализованы начиная с версии 2.0. Ранние версии Visual C++ с ними работать не могли.
Шаблоны предназначены для создания ряда классов и функций, отличающихся только типом обрабатываемых ими данных. Для определения шаблона предназначено ключевое слово template (шаблон). Общий синтаксис определения шаблона имеет следующий вид:
template
Аргумент template-argument-list представляет собой список условных имен для определения типов, по которым будут различаться различные реализации классов или функций данного шаблона.
Шаблоны в MFC
В библиотеке классов MFC определен ряд шаблонов для создания таких структур хранения информации как массив, список, словарь. Более подробно об этих шаблонах вы можете прочитать в разделе “Коллекции” главы “Некоторые классы MFC”.
Перегрузка операторов
Си++ позволяет вам легко вводить новые типы данных. Так, например, вы можете определить класс для работы с комплексными числами или числами в полярной системе координат. Естественно, что удобнее всего проводить вычисления с объектами таких классов при помощи операторов, а не специальных методов или функций.
В Си++ вы можете переопределить большинство операторов языка для работы с вашими типами данных. Вот список операторов, которые вы можете переопределить:
! = < > += –=
!= , –> –>* & |
( ) [ ] new delete >> <<=
^= &= |= << >>= ==
~ *= /= %= % ^
+ - * / ++ --
<= >= && ||
Переопределение операторов вызывает перегрузку операторов. Как в случае перегруженных функций и методов, перегруженные операторы вызываются в зависимости от количества и типа их параметров. О перегруженных функциях вы можете прочитать в разделе “Перегрузка имен функций”.
Для переопределения операторов предназначено ключевое слово operator. Вы должны определить функцию или метод, имя которого состоит из ключевого слова operator и самого оператора. Параметры этой функции должны соответствовать параметрам переопределяемого оператора.
Вы можете переопределить оператор для объектов класса, используя соответствующий метод класса или дружественную функцию класса. Когда вы переопределяете оператор с помощью метода класса, то в качестве неявного параметра метод принимает ключевое слово this, являющееся указателем на данный объект класса. Поэтому если переопределяется бинарный оператор, то переопределяющий его метод класса должен принимать только один параметр, а если переопределяется унарный оператор – метод класса вообще не должен иметь параметров.
Если оператор переопределяется при помощи дружественной функции, то он должен принимать два параметра для бинарных операторов и один параметр для унарных операторов.
Существует ряд ограничений, которые вы должны учитывать при переопределении операторов:
• Нельзя изменять количество параметров оператора. Например, нельзя переопределить унарную операцию как бинарную и наоборот
• Нельзя изменять старшинство операторов