
- •6.050201 «Системная инженерия»
- •Донецк, 2012
- •1 Цели и задачи дисциплины
- •2 Теоретические основы программирования
- •2.1 Основные сведения в области информатики Общее понятие алгоритма
- •Алгоритмические языки
- •Типы переменных
- •Целочисленные переменные
- •Кольцо вычетов по модулю m
- •Интерпретация положительных и отрицательных чисел
- •Вещественные переменные
- •Машинный эпсилон
- •Запись вещественных констант
- •Символьные переменные
- •Логические переменные и выражения
- •Массивы
- •Текстовые строки
- •Оперативная память
- •Процессор
- •Cisc и risc-процессоры
- •Алгоритм работы компьютера
- •Аппаратный стек
- •Команды вызова подпрограммы call и возврата return
- •Аппаратный стек и локальные переменные подпрограммы
- •2.2. Стандарты построения блок-схем алгоритмов
- •4 Компиляция и выполнение программ
- •5 Структурное программирование
- •5.1 Описание переменных
- •Константы
- •Целые числа
- •Вещественные числа
- •Логические величины
- •Символы и байты
- •Кодировка, многобайтовые символы
- •5.2 Основные операции и их приоритет
- •Порядок вычисления выражений
- •5.3 Операторы
- •Операторы цикла
- •5.4 Организация ввода-вывода
- •Манипуляторы и форматирование ввода-вывода
- •Строковые потоки
- •Ввод-вывод файлов
- •5.5 Массивы
- •5.6. Указатели и операции над ними
- •5.7 Ссылки
- •5.8 Динамическое выделение памяти
- •5.9 Функции
- •Подставляемые функции
- •Имена функций
- •Необязательные аргументы функций
- •Рекурсия
- •Назначение шаблонов
- •Функции-шаблоны
- •5.10 Область видимости имен
- •5.11 Сложные структуры данных
- •5.11.1 Структуры
- •5.11.2 Перечисления
- •5.11.3. Объединения
- •5.12. Динамические структуры данных
- •6 Препроцессор
- •Определение макросов
- •Условная компиляция
- •Дополнительные директивы препроцессора
- •7 Объектно-ориентированное программирование
- •7.1 Основные понятия объектно-ориентированного программирования
- •Определение методов класса
- •Виртуальные методы
- •Виртуальные методы и переопределение методов
- •Преобразование базового и производного классов
- •Внутреннее и защищенное наследование
- •Абстрактные классы
- •Множественное наследование
- •Виртуальное наследование
- •Интерфейс и состояние объекта
- •Объявление friend
- •7.2 Конструктор и деструктор класса
- •Копирующий конструктор
- •Деструкторы
- •Инициализация объектов
- •Операции new и delete
- •7.3 Перегрузка операций
- •Как определять операции
- •Преобразования типов
- •Явные преобразования типов
- •Стандартные преобразования типов
- •Преобразования указателей и ссылок
- •Преобразования типов, определенных в программе
- •7.4 Использование включаемых файлов
- •7.5. Шаблоны классов
- •"Интеллигентный указатель"
- •Задание свойств класса
- •8 Обработка исключительных ситуаций
- •Примеры обработки исключительных ситуаций
- •Список использованных источников
Объявление friend
Предположим, мы хотим в дополнение к интерфейсу класса String создать функцию, которая формирует новую строку, являющуюся результатом слияния двух строк, но не изменяет сами аргументы. (Особенно часто подобный интерфейс необходимо создавать при определении операций – см. ниже). Для того чтобы эта функция работала быстро, желательно, чтобы она имела доступ к внутренним атрибутам класса String. Доступ можно разрешить, объявив функцию "другом" класса String с помощью ключевого слова friend:
class String
{
. . .
friend String concat(const String& s1,
const String& s2);
};
Тогда функция concat может быть реализована следующим образом:
String
concat(const String& s1, const String& s2)
{
String result;
result.length = s1.length + s2.length;
result.str = new char[result.length + 1];
if (result.str == 0) {
// обработка ошибки
}
strcpy(result.str, s1.str);
strcat(result.str, s2.str);
return result;
}
С помощью механизма friend можно разрешить обращение к внутренним элементам класса как отдельной функции, отдельному методу другого класса или всем методам другого класса:
class String
{
// все методы класса StringParser обладают
// правом доступа ко всем атрибутам класса
// String
friend class StringParser;
// из класса Lexer только метод CharCounter
// может обращаться к внутренним атрибутам
// String
friend int Lexer::CharCounter(const
String& s, char c);
};
Конечно, злоупотреблять механизмом friend не следует. Каждое решение по использованию friend должно быть продумано. Если только одному методу какого-либо класса действительно необходим доступ, не следует объявлять весь класс как friend.
7.2 Конструктор и деструктор класса
При определении класса имеется возможность задать для объекта начальное значение. Специальный метод класса, называемый конструктором, выполняется каждый раз, когда создается новый объект этого класса. Конструктор – это метод, имя которого совпадает с именем класса. Конструктор не возвращает никакого значения.
Для класса String имеет смысл в качестве начального значения использовать пустую строку:
class String
{
public:
String(); // объявление конструктора
};
// определение конструктора
String::String()
{
str = 0;
length = 0;
}
Определив такой конструктор, мы гарантируем, что даже при создании автоматической переменной объект будет соответствующим образом инициализирован (в отличие от переменных встроенных типов).
Конструктор без аргументов называется стандартным конструктором или конструктором по умолчанию. Можно определить несколько конструкторов с различными наборами аргументов. Возможности инициализации объектов в таком случае расширяются. Для нашего класса строк было бы логично инициализировать переменную с помощью указателя на строку.
class String
{
public:
String(); // стандартный конструктор
String(const char* p);
// дополнительный конструктор
};
// определение второго конструктора
String::String(const char* p)
{
length = strlen(p);
str = new char[length + 1];
if (str == 0) {
// обработка ошибок
}
strcpy(str, p); // копирование строки
}
Теперь можно, создавая переменные типа String, инициализировать их тем или иным образом:
char* cp;
// выполняется стандартный конструктор
String s1;
// выполняется второй конструктор
String s2("Начальное значение");
// выполняется стандартный конструктор
String* sptr = new String;
// выполняется второй конструктор
String* ssptr = new String(cp);