- •Экзамен 374 Предварительные рассуждения Вступительное слово
- •Исторические факты
- •Начнем!
- •Проба пера
- •Открытие сохраненного проекта
- •Вывод данных
- •Типы данных
- •Хороший стиль программирования
- •Переменные и константы
- •Практический пример
- •Ввод данных
- •Например:
- •Пример:
- •Арифметические операции с числами
- •Литералы
- •Некоторые примеры
- •Домашнее задание
- •Напишите программу, которая вводит число из трех цифр, разделяет число на отдельные цифры и печатает их отдельно друг от друга с тремя пробелами между ними. Преобразование типов
- •Перечисляемые типы
- •Типичная ошибка
- •Хороший стиль программирования
- •Типичная ошибка
- •Выражения
- •Оператор if
- •Структура программы
- •Логические операции
- •Структура множественного выбора switch
- •Практический пример
- •Цикл for
- •Практический пример
- •Цикл do-while
- •Домашнее задание
- •Вызов функции
- •Прототипы функций
- •Разбор программы
- •Область видимости
- •Аргументы по умолчанию
- •Встраивание
- •Перегрузка функций
- •Учебный пример перегруженных функций. Иллюстрация перегрузки
- •Результат работы программы
- •Практические примеры
- •Домашнее задание
- •Примеры домашней работы урока 1 Пример №1
- •Как работает программа
- •Пример №2
- •Как работает программа
- •Примеры домашних работ на создание функций Пример №1
- •Как работает программа
- •Пример №2
- •Как работает программа
- •Массивы
- •Объявление массивов
- •Примеры использования массивов
- •Программа 1
- •Программа 2
- •Обратите внимание!
- •Типичная ошибка программирования
- •Типичная ошибка программирования
- •Программа 3
- •Типичная ошибка программирования
- •Замечание по технике программирования
- •Программа 4
- •Программа 5
- •Программа нахождения минимального и максимального элементов массива
- •Сортировка массивов
- •Домашнее задание
- •Что такое указатели?
- •За кулисами...
- •Как работать с указателями?..
- •Зачем нужны указатели?
- •Указатели и Массивы.
- •Примеры задач
- •Пример 1
- •Пример 2
- •Пример 3
- •Указатели - аргументы функций.
- •Ссылочные параметры
- •Примеры решения задач
- •Домашнее задание
- •Операторы свободной памяти new и delete
- •Функции работы со строками из библиотеки обработки строк
- •Пример 1.
- •Пример2
- •Пример 3
- •Пример задачи на новый материал
- •Домашнее задание
- •Двухмерные массивы, как частный случай многомерных массивов
- •Программа.
- •Результаты работы программы.
- •Многомерные динамические массивы
- •Пример на многомерные динамические массивы
- •Домашнее задание
- •Рекурсия
- •Рекурсии или итерации
- •Указатели на функции
- •Пример №1
- •Результат выполнения программы:
- •Пример №2
- •Результат выполнения программы
- •Пример №3
- •Результаты выполнения программы
- •Определения структур
- •Пример #1 на использование структур
- •Пример #2 на использование структур
- •Оператор указателя на структуру
- •Домашнее задание
- •Тест по c Группа ___________________ф. И. О. ______________________
- •Объектно-ориентированное программирование.
- •Наследование (Inheritance).
- •Инкапсуляция (Encapsulation).
- •Определение класса
- •Конструкторы и деструкторы Инициализация объектов класса: конструкторы
- •Основное назначение конструкторов - инициализация объектов.
- •Использование конструкторов с аргументами по умолчанию
- •Если параметры не передаются конструктору, в определении объекта не нужно включать пустые круглые скобки.
- •Использование деструкторов
- •Когда вызываются конструкторы и деструкторы.
- •Домашнее задание
- •Конструктор копирования
- •Синтаксис конструктора копирования
- •Памятка
- •Пример использования конструктора копирования.
- •Перегруженные конструкторы
- •Экскурс в историю
- •Послесловие к примеру
- •Маленькое замечание
- •Домашнее задание
- •Создание класса ''строка''
- •Перегрузка операций.
- •Общие принципы перегрузки операторов.
- •Преобразования, определяемые классом
- •Пример строкового класса с перегруженными операторами
- •Домашнее задание
- •Дружественные функции (Friend Functions)
- •Пример строкового класса с перегруженными операторами и дружественными функциями
- •Перегрузка операторов new и delete
- •Перегрузка оператора индексирования
- •Класс вектор. Часть1.
- •Класс вектор. Часть 2.
- •Класс вектор. Часть 3.
- •Домашнее задание
- •Наследование (Inheritance). Часть 1.
- •Наследование (Inheritance). Часть 2.
- •Множественное наследование (multiple inheritance)
- •Пример множественного наследования
- •Домашнее задание
- •Статические члены данных
- •Раннее и позднее связывание
- •Виртуальные функции
- •Пример.
- •Абстрактные классы
- •Виртуальный базовый класс
- •Практический пример
- •Домашнее задание
- •Потоки ввода-вывода.
- •Iostream.H: stream - поток, "I" - сокр. Input - ввод, "o" - сокр. Output - вывод.
- •Предопределенные потоки.
- •Операции помещения в поток и извлечения из потока.
- •Файловый ввод-вывод с применением потоков.
- •Конструкторы файловых потоков.
- •Функции для открытия и закрытия файлов.
- •Функции для обмена с потоками.
- •Часто применяемые функции потока.
- •Ввод/вывод массива в/из файл(-а).
- •Практический пример: перекодировка файла.
- •Домашнее задание
- •Немного о файлах...
- •И снова файлы...
- •Пример "Телефонная книга"
- •Файл abonent.H
- •Форматирование данных при обменах с потоками.
- •Состояние потока.
- •Использование аргументов командной строки.
- •Ввод/вывод в с.
- •Домашнее задание
- •Определение шаблонов функций
- •Переопределение шаблонов функций
- •Шаблоны классов
- •Шаблонный класс вектор
- •Шаблонный класс вектор
- •Шаблонный класс вектор
- •Введение
- •Обработка исключительных ситуаций
- •Практический пример
- •Программа
- •Домашнее задание
- •Экзамен
Преобразования, определяемые классом
Конструктор с одним аргументом автоматически является функцией преобразования из типа аргумента к типу конструируемого класса. Рассмотренный ранее строковый класс имел следующий конструктор:
string::string(const char* s)
{
len = strlen(s);
S = new char[len + 1];
strcpy(S, s);
}
Представленное выражение - автоматическое преобразование типа от char* к string. Оно доступно как явно, так и неявно. Явно оно используется или как операция преобразования, или в приведении, или в функциональной форме. Таким образом, возможны два рабочих варианта кода:
string s;
char str[] = "Hello\n";
s = (string)str; // Выполняет преобразование, а затем присвоение
и
s = str; // Неявный вызов преобразования
Данный код - преобразование из уже определенного типа к типу, определяемому пользователем. Однако возможна обратная ситуация: в примере со строкой может возникнуть необходимость в преобразовании из строки в char*. Это может быть выполнено с помощью определения специальной функции преобразования внутри класса string следующим образом:
operator char*() { return S; }
Общая форма записи такой функции-члена:
operator тип() { ... }
Такая функция преобразования должна быть функцией-членом без возвращаемого типа и с пустым списком аргументов. Преобразования происходят неявно в выражениях присвоения, при передаче параметров функциям, и в значениях, возвращаемых функциями.
Пример строкового класса с перегруженными операторами
Рассмотрим следующую задачу: необходимо добавить в строковый класс, функцию сцепления строк, используя перегрузку бинарного оператора +. реализовать функции ввода-вывода строк и сортировки строк.
Для решения данной задачи воспользуемся материалами данного урока.
#include <string.h>
#include <iostream.h>
class string // Объявление строкового класса
{
private:
char* S; // Строка
int len; // Длина строки
public:
string(); // Конструктор по умолчанию
string(const char* s); // Перегруженный конструктор
string(const string& s); // Конструктор копирования
~string() { delete [] S; }// Деструктор
// Перегрузка бинарного оператора
// Первый параметр передается неявно с помощью указателя this
// Функция реализует сцепление строк
string operator+(const string&);
// Перегрузка бинарного оператора
// Первый параметр передается неявно с помощью указателя this
// Функция реализует корректное присваивание объектов друг другу
string& operator=(const string&);
// Перегрузка типа
// Функция реализует преобразование объекта класса к типу char*
operator char*() { return S; }
void Sort(string s[], int n); // Функция сортировки
int GetLen() { return len; } // Функция возвращает длину строки
};
string::string()
{
S = new char[81]; // Выделение памяти под 81 элемент
// строки для объекта по умолчанию
for(int i = 0; i < 81; i++)
S[i] = 0;
len = 80;
}
string::string(const char* s)
{
len = strlen(s);
S = new char[len + 1];
strcpy(S, s); // Инициализация строкой, переданной
// пользователем
}
string::string(const string& s)
{
len = s.len;
S = new char[len + 1]; // Безопасное копирование
strcpy(S, s.S);
}
void string::Sort(string s[], int n)
{ // Сортировка строк
bool flag = true;
string temp;
for(int j = 1; ; j++)
{
for(int i = 0; i < n - j; i++)
if(strcmp(s[i], s[i + 1]) > 0) // Происходит обращение к
{ // строкам напрямую, благодаря
// неявному вызову функции класса string
// operator char*()
temp = s[i]; // Вызов функции operator=(s[i])
s[i] = s[i + 1]; // Вызов функции operator=(s[i + 1])
s[i + 1] = temp; // Вызов функции operator=(temp)
flag = false;
}
if(flag)
break;
flag = true;
}
}
string string::operator+(const string &str)
{ // Функция сцепления строк
string s; // Создание временного объекта
delete [] s.S; // Удаление старой строки
s.len = len + str.len; // Вычисление новой длины строки
s.S = new char[s.len + 1]; // Выделение памяти под новую строку
strcpy(s.S, S); // Инициализация первой части строки
strcat(s.S, str.S); // Инициализация второй части строки
return s; // Возврат нового объекта
}
string& string::operator=(const string &str)
{ // Функция, реализующая безопасное присваивание
delete [] S; // Удаление старой строки
len = str.len; // Вычисление новой длины строки
S = new char[len + 1]; // Выделение памяти под новую строку
strcpy(S, str.S); // Инициализация строки
return *this; // Возврат ссылки на "самого себя"
// Благодаря этому возможно многократное
// присваивание объектов друг другу
// например, string a, b, c; a = b = c;
}
void main(void)
{
string a, b, c;
cout << "Input the first part of string:\t";
cin.getline(a, a.GetLen());
cout << "Input the second part of string:\t";
cin.getline(b, b.GetLen());
// Использывались неявные вызовы функций
// a.operator char*() и b.operator char*()
c = a + b + "\nThat's all !\n";
// Произошел вызов конструктора преобразования
// для строки "\nThat's all !\n"
cout << c; // Вывод результирующей строки
// Неявный вызов функции c.operator char*()
}