- •Экзамен 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
- •Форматирование данных при обменах с потоками.
- •Состояние потока.
- •Использование аргументов командной строки.
- •Ввод/вывод в с.
- •Домашнее задание
- •Определение шаблонов функций
- •Переопределение шаблонов функций
- •Шаблоны классов
- •Шаблонный класс вектор
- •Шаблонный класс вектор
- •Шаблонный класс вектор
- •Введение
- •Обработка исключительных ситуаций
- •Практический пример
- •Программа
- •Домашнее задание
- •Экзамен
Домашнее задание
Задания первого уровня:
Цифровой счетчик, это переменная с ограниченным диапазоном. Значение которой сбрасывается, когда ее целочисленное значение достигает определенного максимума (например, k принимает значения в диапазоне от 0..100). В качестве примера такого счетчика можно привести цифровые часы, счетчик километража. Опишите класс такого счетчика. Обеспечьте возможность установления максимального и минимального значений, увелечения счетчика на 1, возвращения текущего значения.
Определите класс дробей - рациональных чисел, являющихся отношением двух чисел (а/b). Напишите методы для сложения, вычитания, умножения и деления дробей.
Задания второго уровня:
К заданию первого уровня: "Определите класс дробей - рациональных чисел, являющихся отношением двух чисел (а/b). Напишите методы для сложения, вычитания, умножения и деления дробей.", - добавьте возможность приведения дроби к наименьшему знаменателю.
Конструктор копирования
Ну что ж, приступим! Сконцетрируйтесь, закройте глаза. Подумайте о чем-то хорошем. Я надеюсь, Вы подумали о С++. Отдохнули?
Продолжаем наше погружение в прекрасный мир совершенного языка. По крайней мере, некоторые так думают. По умолчанию, при инициализации одного объекта другим, С++ выполняет побитовое копирование (почленное копирование). Сильно сказано. Это означает, что один объект становится точной копией другого. Продемонстрируем всё вышесказанное на примере:
#include<iostream.h>
class A{
int a;
public:
void Set(int f){
a=f;
}
};
void main(){
A ist;
ist.Set(4);
A cpy=ist;//После выполнения этой строки cpy будет копией ist
}
Хотя в большинстве случаев в этом нет ничего страшного, существуют ситуации, когда побитовое копирование не должно использоваться. Например, когда объект выделяет память при своем создании:
Пример
Пусть у нас есть 2 обьекта G и J класса MyClass, выделяющего память при создании обьекта.Предположим, что обьект G уже существует. Это означает что обьект G уже выделил память. Далее предположим, что G использовался для инициализации обьекта J, как показано ниже:
MyClass J=G;
Если в данном случае используется побитовое копирование( почленное копирование). То J станет копией G. Это значит, что J будет использовать тот же участок выделенной памяти, что и G,вместо того, чтобы выделить свой. Это чрезвычайно плохо. Если например в классе MyClass есть деструктор, освобождающий память, то тогда одна и та же память будет очищена дважды при уничтожении G и J.
#include<iostream.h>
// Реализация описанного выше
class MyClass{
public:
int *x;
MyClass(){
x=new int;
}
~MyClass(){
delete x;
}
};
void main(){
// при создании обьекта G выделяется память в теле конструкторе
MyClass G;
// Вот-то и возникает проблема снова создаётся обьект,
// а память в конструкторе не выделяется.В итоге указатель
// J.x указывает в ту же область память ,что и G.x
MyClass J=G;
// при выходе из функции main 2 раза вызывается деструктор,
// который очищает память отведённую при создании обьекта
// то есть выполняется delete x для J и delete x для G
// а так как J.x=G.x то отсюда следует вывод, что 2 раза
// очищается одна и та же область памяти. Это повлечет за
// собой ошибку на этапе выполнения программы
}
Проблема того же типа может возникнуть ещё в 2х случаях. Первый из них возникает, когда обьекта передается по значению в функцию в качестве аргумента:
#include<iostream.h>
class MyClass{
public:
int *x;
MyClass(){
x=new int;
}
~MyClass(){
delete x;
}
};
void f(MyClass d){
}
void main(){
// при создании обьекта G выделяется память в теле конструкторе
MyClass G;
// При передаче в функцию обьекта G по значению будет создана
// дополнительная копия обьекта.Это будет проделано с помощью
// побитового копирования (т.е. как обьяснялось выше память не будет
// выделена)
f(G);
}
Опять же возникнет ошибка на этапе выполнения программы !!!
Второй появляется , когда временный обьект создается
функцией возвращающей обьект в качестве своего значения.
Пример :
#include<iostream.h>
class MyClass{
public:
int *x;
MyClass(){
x=new int;
cout<<"It's me";
}
~MyClass(){
delete x;
}
};
MyClass f(){
MyClass s;
// та же ошибка!!! При возврате значения создаётся побитовая копия
// под которую не выделяется память
return s;
}
void main(){
f();
}
конструктор копирования