
- •Структуры
- •Массив структур
- •Указатели на структуру
- •Битовые поля
- •Объединения
- •Перечисления
- •Переименование типов
- •Открытие файла
- •Функции работы с файлами
- •Форматный ввод/вывод
- •Ввод/вывод строк. Функции позиционирования
- •Чтение из двоичного файла и запись в него
- •Свойства ООП
- •1.1 Свойства ООП
- •Понятие класса в С++
- •1.2 Понятие класса С++
- •Создание класса
- •1.3 Создание класса
- •Члены класса
- •1.4 Члены класса
- •Инкапсуляция
- •1.5. Инкапсуляция
- •1.6 Функции-члены класса
- •Реализация понятия «дата» при помощи структуры
- •1.7 Реализация понятия «дата» при помощи структуры
- •Реализация понятия «дата» при помощи класса
- •1.8 Реализация понятия «дата» при помощи класса
- •Определение и вызов функций–членов класса
- •Выводы. Примеры
- •1.9 Выводы
- •1.10 Пример создания класса
- •Конструкторы
- •2.1 Конструкторы
- •2.2 Пример класса без конструктора
- •2.3 Пример класса с конструктором
- •2.4. Конструктор с параметрами по умолчанию
- •2.5. Деструкторы
- •2.6. Пример класса с конструктором и деструктором
- •2.7. Подставляемые или inline функции.
- •2.8. Подставляемые функции-члены.
- •2.9. Указатель this
- •2.10. Использование указателя this
- •Дружественные функции
- •3.1 Дружественные функции
- •3.2 Пример дружественной функции
- •3.3 Дружественные классы
- •3.4. Уточнение имени элемента.
- •3.5. Определение переменных непосредственно перед использованием
- •3.6. Статические элементы класса.
- •2.7. Пример
- •Перегруженные функции
- •4. Перегрузка функций и операций
- •4.1 Полиморфизм
- •4.2 Перегруженные функции
- •4.3 Перегрузка конструктора
- •4.4 Выбор экземпляра функции
- •4.5 Перегрузка стандартных операций
- •4.6 Перегрузка операций сложения и присваивания
- •4.7 Перегрузка операций ++ и --
- •4.8 Дружественные функции-операции
- •4.9 Перегрузка операции индексации []
- •4.10 Аргументы по умолчанию
- •5. Работа с объектами
- •5.1 Ссылки в С++
- •5.2 Передача объектов, как аргументов функции
- •5.3 Массивы объектов
- •5.4 Указатель на объект
- •5.5 Динамическое выделение памяти. Операторы new, delete.
- •5.6 Локальные классы
- •5.7 Вложенные классы
- •5.8 Имена заголовочных файлов в С++
- •5.9 Строковые переменные в С++.
- •6. Наследование
- •6.1 Понятие наследования
- •6.2 Базовые и производные классы
- •6.3 Одиночное и множественное наследование
- •6.4 Управление доступом производных классов
- •6.5 Пример
- •6.6 Конструкторы с параметрами при наследовании
- •6.7 Конструкторы при множественном наследовании
- •7. Виртуальные функции. абстрактные классы
- •7.1 Указатели на производные типы
- •7.2 Виртуальные функции
- •7.3 Пример
- •7.4 Чистые виртуальные функции и абстрактные типы
- •7.5 Виртуальные базовые классы
- •7.6 Шаблоны
- •7.7 Шаблоны функций
- •7.8 Пример
- •7.9 Использование шаблонов с двумя типами параметров
- •7.10 Шаблоны классов
Наиболее часто такая запись используется для того, чтобы использовать имена общеизвестных функций (printf, open), как имена функции–членов.
Пример:
class my_file
{
…
public:
int open (char *, char *);}
int my_file :: open (char * name, char * spee)
{
…
if (:: open (name, flag)) {…}
};
3.5. Определение переменных непосредственно перед использованием
Между С и С++ существуют значительные различия относительно определения переменных. Оба языка требуют, чтобы переменные определялись перед использованием, но С заставляет определять все переменные в начале области видимости, чтобы компилятор мог выделить память для этих переменных.
Язык С++ позволяет определять переменные в произвольной точке области видимости, то есть переменная может определяться непосредственно перед использованием. Кроме того, возможна инициализация переменных в точке определения, что предотвращает некоторые коды ошибок.
Переменные также могут определяться в управляющих выражениях циклов for и while, в условиях команд if и в критериях выбора команды switch. Рассмотрим пример определения переменных непосредственно перед использованием.
#include <iostream>
using namespace std;
main () {
{//Начало новой области видимости
int q;
// Определение переменных перед использованием
for(int i=0; i<100; i++) {
q++;
// Определение в конце области видимости
int p=12;
}
int p=1; //Другая переменная p
} //Завершение области видимости, содержащей q и внешнюю переменную p
while (char c=getch() != ‘q’)
cout << c;
}
Во внутренней области видимости переменная p определяется перед концом области видимости. Это объявление абсолютно бесполезно, но оно показывает, что переменные действительно могут определяться в любой точке области видимости. То же самое можно сказать о переменной p из внешней области видимости.
Определение i в управляющем выражении цикла for – пример определения переменной прямо в момент использования. Область видимости i ограничивается данным циклом for, поэтому ничто не помешает заново определить переменную с именем i для следующего цикла for.
Использование определения переменных в командах while, if, switch происходит значительно реже определения в циклах for. Возможно, это объясняется ограничениями синтаксиса. Например, выражением не может содержать круглых скобок, т.е. следующая конструкция невозможна:
while ((char c=getch()) != ‘q’)
Без круглых скобок результат выглядит не так, как следовало ожидать. Проблемы возникают из-за того, что оператор != обладает более высоким приоритетом, чем =, поэтому переменной char в конечном счете присваивается значение bool, приведенное к типу char.
3.6. Статические элементы класса.
Класс – это тип, а не объект данных. Для каждого объекта класса существует своя копия элементов класса, но часто бывает необходимо, чтобы все объекты одного класса совместно пользовались одними данными. Это можно осуществить, используя глобальную переменную. Но иногда желательно объявить совместно используемые данные частью класса (обеспечить санкционированный доступ). Этого можно достигнуть, объявив соответствующие данные статическими элементами класса. Статический элемент является общим для всех объектов этого класса.
В отличие от обычного элемента класса статический элемент не исчезает при удалении объекта. В некотором смысле статические переменные напоминают глобальные переменные программы. Однако статические переменные, в отличие от глобальных
переменных, полностью согласуются с принципами объектно-ориентированного программирования, в частности с принципом инкапсуляции. Статические элементы объявляются, как и обычные, но перед статическим элементом указывается ключевое слово static.
Объявление статических элементов только в классе не приводит к реальному резервированию памяти, как это происходит в случае с нестатическими даннымичленами, а попытка сразу использовать статические элементы приведет к ошибке компоновщика, который будет пытаться разрешить внешнюю ссылку (именно так представляет компилятор статические данные). Для реального выделения и инициализации памяти следует сделать еще одно объявление данных отдельно, вне класса, придерживаясь при этом правила одного определения, т. е. такое дополнительное определение должно быть единственным в программе. Обычно это дополнительное определение статических данных делают в файле, где объявлен класс.
Пример. Реализации списка всех задач.
class task
{
…
task *next;
static task *task_chain;
void schedule (int);
void wait (event);
…
};
Описание task_chain, как статического элемента, обеспечивает условие, что цепочка задач будет всего одна, а не по одной копии на каждый объект task. Переменная находится в области действия класса task, обратиться из вне к ней нельзя (только объявив как public).
Использование статических объектов сокращает потребность глобальных переменных.
2.7. Пример
Пример:
#include<iostream>
#include<conio.h>
using namespace std;
class Sale
{ public:
/*статическое поле amount класса Sale */
static int amount;
double price; //цена товара
int number; //количество товара
};
int Sale::amount; /* Повторное объявление статической переменной. Оно выполняется для выделения места в памяти под эту переменную */
int main() {
setlocale(LC_ALL, "Russian");
Sale Product1, Product2; /* создание объектов
cout << "Количество = " << Sale::amount; /* Для обращения к статическому полю используется имя класса, а не имя объекта. На экран будет выведен 0,
т.к. статическому полю типа int при объявлении присваивается ноль */
Product1.price=25.5;
Product1.number=5;
Product1.amount++; /* обращение к статическому полю возможно через объект */
cout<< "Количество = " << Sale::amount;
Product2.price=36.9;
Product2.number=7;
Product2.amount ++; /* статическое поле одно для всех объектов */
cout<< "Количество = " << Sale::amount;
Sale::amount++; /* значение статического поля одно для всех объектов, поэтому следующая команда выведет три одинаковых значения */
cout<< "Количество="<< Product1.amount<< Product2.amount << Sale::amount ;
return 0;
}