- •Предисловие
- •Введение
- •Введение в программирование
- •1.1. Предисловие к курсу
- •1.2. Идеология языка
- •1.3. Обзор среды Microsoft Developer Studio
- •1.4. Жизненный цикл программного обеспечения
- •1.5. Общая структура программы
- •1.6. Директивы препроцессора
- •1.7. Построение исполняемого файла
- •1.8. Строительные блоки программы
- •Контрольные вопросы
- •Типы данных. Переменные. Массивы. Операции и Указатели
- •Стандартные типы и размеры данных
- •2.1.1. Объявление переменных
- •Управляющие символьные константы
- •2.2. Объявление указателя
- •2.2.1. Операции разыменования и взятия адреса
- •2.2.2. Указатели на указатели
- •2.2.3. Арифметические операции с указателями
- •2.3. Массивы
- •2.3.1. Инициализация массивов
- •2.3.2 Динамические массивы
- •2.3.3. Методы доступа к элементам массивов
- •2.3.4. Массивы указателей
- •2.4. Строки
- •2.5. Операции
- •2.5.1. Арифметические операции
- •Арифметические операции
- •2.5.2 Операции сравнения и логические операции
- •Операции сравнения и логические операции
- •2.5.3. Побитовые операции
- •Побитовые операции
- •Контрольные вопросы
- •3.1. Базовые операторы
- •3.1.1. Оператор выражение
- •3.2.2. Оператор switch
- •3.3.4. Оператор goto
- •3.4. Операторы цикла
- •3.4.1. Оператор for
- •3.4.2. Оператор while
- •3.4.3. Оператор do..While
- •Контрольные вопросы
- •Стандартный ввод/вывод. Работа с файлами.
- •4.1. Роль стандартного ввода/вывода
- •4.1.1. Основные функции стандартного ввода/вывода
- •4.2. Понятие файла
- •4.2.1. Строение файлов
- •4.2.2. Порядок работы с файлом
- •4.2.3. Обзор библиотечных функций с для работы с файлами
- •4.3. Программные конструкции при работе с файлами
- •4.3.1. Открытие/закрытие файла
- •4.3.2. Цикл посимвольного чтения содержимого файла
- •4.3.3. Цикл построчного чтения содержимого файла
- •Контрольные вопросы
- •Функция. Пользовательские типы данных.
- •5.1. Понятие функции
- •5.1.1. Определение функции
- •5.1.2. Формальные параметры
- •5.1.3. Тип возвращаемого значения
- •5.1.4. Тело функции
- •5.1.5. Фактические параметры
- •5.1.6. Рекурсивные вызовы
- •5.1.7. Передача параметров
- •5.1.8. Библиотеки стандартных функций
- •5.2. Пользовательские типы данных.
- •5.2.1. Ключевое слово typedef
- •5.2.2. Перечислимый тип данных
- •5.2.3. Понятие структуры
- •5.2.4. Указатели на структурный объект
- •Контрольные вопросы
- •Работа с динамической памятью. Динамические структуры данных
- •6.1. Работа с динамической памятью
- •6.1.1. Статическое и динамическое распределение памяти
- •6.1.2. Основные принципы динамического распределения
- •6.1.3. Способы работы с динамической памятью
- •6.2. Динамические структуры данных
- •6.2.1. Стек
- •6.2.2.Линейный список
- •Контрольные вопросы
- •Объектно-ориентированное программирование
- •7.1. Критерии качества декомпозиции проекта
- •7.2. Новые концепции программирования
- •7.3. Достоинства ооп
- •7.4. Объекты и классы в ооп
- •7.4.1. Определение класса
- •7.4.2. Использование класса
- •7.4.3. Вложенные классы
- •Контрольные вопросы
- •Конструкторы и Перегрузка операций.
- •8.1. Перегрузка операций
- •8.1.1. Перегрузка операций внешними функциями
- •8.1.2. Перегрузка операций методами класса
- •8.2. Конструкторы и деструктор
- •8.2.1. Конструкторы и параметры
- •Контрольные вопросы
- •9.1. Простое открытое наследование
- •9.1.1 Конструкторы и деструкторы при наследовании
- •9.1.2. Поля и методы при наследовании
- •9.1.3. Вложенные классы и наследование
- •9.1.4. Закрытое наследование
- •9.1.5. Виртуальные функции
- •9.1.6. Чистые виртуальные функции и абстрактные классы
- •9.3. Основы программирования под Windows
- •9.3.1. Типы данных в Windows
- •9.4. Cреда Microsoft Developer Studio
- •9.4.1. Библиотека mfc
- •9.4.2. Архитектура приложения
- •9.4.3. Каркас приложения
- •9.4.4. Проект приложения
- •Контрольные вопросы
- •Заключение
- •Список Литературы
9.1.2. Поля и методы при наследовании
Класс-потомок наследует структуру (все элементы данных) и поведение (все методы) базового класса. Класс-наследник получает в наследство все поля базового класса (хотя, если они были приватные, доступа к ним не имеет). Если новые поля не добавляются, размер класса-наследника совпадает с размером базового класса. Порожденный класс может добавить собственные поля:
class Point2
{ int x; int у;
public: // ...
};
class Point3: public Point2
{ int z;
public: // ...
};
Добавляемые поля должен инициализировать конструктор наследника. Дополнительные поля производного класса могут совпадать и по имени, и по типу с полями базового класса – в этом случае новое поле скрывает поле базового класса, поэтому для доступа к последнему полю в классе-наследнике необходимо использовать префикс-квалификатор базового класса.
Класс-потомок наследует все методы базового класса, кроме операции присваивания – она создается для нового класса автоматически, если не определена явно. В классе-наследнике можно определять новые методы. В новых методах разрешается вызывать любые доступные методы базового класса.
Если в классе-наследнике имя метода и его прототип совпадают с именем метода базового класса, то говорят, что метод производного класса скрывает метод базового класса. Чтобы вызвать метод родительского класса, нужно указывать его с квалификатором класса. Пример текста программы наследование методов:
class Base
{ int f; int m;
publiс:
Base():f(),m(){} // конструктор без аргументов
Base (int t, int r = 0) // конструктор инициализации
{ f = t; m = r; }
Base& operator++() // префиксный инкремент
{ f++; return *this; }
Base operator++(int) // постфиксный инкремент
{ F t = *this; f++; return t; }
Base& operator+=(const F& r) // сложение с присваиванием
{ f+=r.f; m+=r.m; return *this; }
};
class Derive: public Base
{ public:
Derive& operator--() // новый метод: префиксный декремент
{ f--: return *this; }
};
9.1.3. Вложенные классы и наследование
Ограничений в наследовании вложенных классов нет: внешний класс может наследовать от вложенного и наоборот; вложенный класс может наследовать от вложенного.
class A {}; // внешний класс
class В {
public:
class С: public A {}: // вложенный класс наследует от внешнего
};
class D: public В:: С {}; // внешний класс наследует от вложенного
class E
{ class F: public B::C {}; // вложенный класс наследует от вложенного
};
Нужно следить только за видимостью базового класса в точке наследования. Например, от вложенного класса Е::F «снаружи» наследовать нельзя, так как класс находится в приватной части класса Е и вне его – невидим. Однако допустимо, чтобы еще один вложенный класс внутри Е наследовал от вложенного класса Е::F:
class E
{ class F: public В: :С {};
class G: public F {};
};
9.1.4. Закрытое наследование
Закрытое наследование – это наследование реализации: класс реализован посредством класса. Оно принципиально отличается от открытого: принцип подстановки не соблюдается. Это означает, что нельзя присвоить (во всяком случае, без явного преобразования типа) объект производного класса базовому. Поэтому закрытое наследование хорошо применять в тех случаях, когда требуется иметь функциональность базового класса, но не нужны ни копирование, ни присваивание.
При закрытом наследовании все элементы класса-наследника становятся приватными и недоступными программе-клиенту.
class Base
{ public:
void methodK);
void method2();
};
class Derive: private Base // наследуемые методы недоступны клиенту
{ };
Программа, использующая класс Derive, не может вызвать ни methodK), ни method2(). В наследнике нужно заново реализовать нужные методы, вызвав в методах наследника методы родителя.
class Derive: private Base // наследуемые методы недоступны клиенту
{ public:
void methodK) { Base: :methodl(); }
void method2() { Base::method2(): }: }:
Префикс при вызове задавать обязательно, иначе возникает рекурсивное обращение к методу-наследнику.
Можно открыть методы базового класса с помощью using-объявления, которое имеет следующий синтаксис:
using <имя базового класса>::<имя в базовом классе>: В наследуемом классе это делается так:
class Derive: private Base // наследуемые методы недоступны клиенту
{ public:
using Base::methodl(); }:
Таким образом, закрытое наследование позволяет ограничить предоставляемую производным классам функциональность.