- •Содержание
- •ВВЕДЕНИЕ
- •1.ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ ПОДХОД
- •2. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ
- •2.1. Абстрактные типы данных
- •2.2. Базовые принципы объектно-ориентированного программирования
- •2.3. Основные достоинства языка С++
- •2.4. Особенности языка С++
- •2.4.1. Ключевые слова
- •2.4.2. Константы и переменные
- •2.4.3. Операции
- •2.4.4. Типы данных
- •2.4.5. Передача аргументов функции по умолчанию
- •2.5.1. Объект cin
- •2.5.2. Объект cout
- •2.5.3. Манипуляторы
- •3.1. Объекты
- •3.2. Понятие класса
- •3.3. Конструктор копирования
- •3.4. Конструктор explicit
- •3.5. Указатель this
- •3.6. Встроенные функции (спецификатор inline)
- •3.7. Организация внешнего доступа к локальным компонентам класса (спецификатор friend)
- •3.8. Вложенные классы
- •3.9. Static-члены (данные) класса
- •3.10. Компоненты-функции static и const
- •3.11. Proxi-классы
- •3.12. Ссылки
- •3.12.1. Параметры ссылки
- •3.12.2. Независимые ссылки
- •3.13. Пространства имен
- •3.13.3. Ключевое слово using как объявление
- •3.13.4. Псевдоним пространства имен
- •3.14. Практические приемы ограничения числа объектов класса
- •4. НАСЛЕДОВАНИЕ
- •4.1.1. Конструкторы и деструкторы при наследовании
- •4.2. Виртуальные функции
- •4.3. Абстрактные классы
- •4.4. Виртуальные деструкторы
- •4.6. Виртуальное наследование
- •5.2. Перегрузка операторов
- •5.2.2. Перегрузка унарного оператора
- •5.2.3. Дружественная функция operator
- •5.2.4. Особенности перегрузки операции =
- •5.2.5. Перегрузка оператора []
- •5.2.6. Перегрузка оператора ()
- •5.2.7. Перегрузка оператора ->
- •5.2.8. Перегрузка операторов new и delete
- •5.3. Преобразование типа
- •5.3.1. Явные преобразования типов
- •6. ШАБЛОНЫ
- •6.1. Параметризированные классы
- •6.2. Передача в шаблон класса дополнительных параметров
- •6.3. Шаблоны функций
- •6.4. Совместное использование шаблонов и наследования
- •6.5. Шаблоны класса и friend-функции
- •6.6. Некоторые примеры использования шаблона класса
- •6.6.1. Реализация smart-указателя
- •6.6.2. Задание значений параметров класса по умолчанию
- •7.2. Состояние потока
- •7.3. Строковые потоки
- •7.4. Организация работы с файлами
- •7.5. Организация файла последовательного доступа
- •7.6. Создание файла произвольного доступа
- •7.7. Основные функции классов ios, istream, ostream
- •8. ИСКЛЮЧЕНИЯ В С++
- •8.2. Перенаправление исключительных ситуаций
- •8.3. Исключительная ситуация, генерируемая оператором new
- •8.6. Спецификации исключительных ситуаций
- •8.7. Задание собственного неожиданного обработчика
- •9. СТАНДАРТНАЯ БИБЛИОТЕКА ШАБЛОНОВ (STL)
- •9.3. Категории итераторов
- •9.4. Операции с итераторами
- •9.5. Контейнеры последовательностей
- •9.5.2. Контейнер последовательностей list
- •9.5.3. Контейнер последовательностей deque
- •9.6. Ассоциативные контейнеры
- •9.6.1. Ассоциативный контейнер multiset
- •9.6.2. Ассоциативный контейнер set
- •9.6.3. Ассоциативный контейнер multimap
- •9.7.1. Адаптер stack
- •9.7.2. Адаптер queue
- •9.7.3. Адаптер priority_queue
- •9.8. Алгоритмы
- •9.8.1. Алгоритмы сортировки sort, partial_sort, sort_heap
- •9.8.2. Алгоритмы поиска find, find_if, find_end, binary_search
- •9.8.3. Алгоритмы fill, fill_n, generate и generate_n
- •9.8.4. Алгоритмы equal, mismatch и lexicographical_compare
- •9.8.6. Алгоритмы работы с множествами
- •9.8.7. Алгоритмы swap, iter_swap и swap_ranges
- •9.8.8. Алгоритмы copy, copy_backward, merge, unique и reverse
- •10. ПРИМЕРЫ РЕАЛИЗАЦИИ КОНТЕЙНЕРНЫХ КЛАССОВ
- •10.1. Связанные списки
- •10.1.1. Реализация односвязного списка
- •10.2. Реализация бинарного дерева
- •11. ПРОГРАММИРОВАНИЕ ДЛЯ WINDOWS
- •11.1. Система, управляемая сообщениями
- •11.2. Управление графическим выводом
- •11.3. Контекст устройства
- •11.3.1. Экран
- •11.3.2. Принтер
- •11.3.3. Объект в памяти
- •11.3.4. Информационный контекст
- •11.4. Архитектура, управляемая событиями
- •11.5. Исходный текст программы
- •11.7. Некоторые новые типы данных
- •11.8. Венгерская нотация
- •11.9. Точка входа программы
- •11.11. Создание окна
- •11.12. Цикл обработки сообщений
- •11.13. Оконная процедура
- •11.14. Обработка сообщений
- •11.15. Обработка сообщений функцией DefWindowProc
- •11.16. Синхронные и асинхронные сообщения
- •11.17. Еще один метод получения описателя контекста устройства
- •11.19. Полосы прокрутки
- •Литература
6. Возникнут ли ошибки при компиляции данной программы, если да, то почему:
|
int i=5; |
|
|
|
|
|
|
|
|
|
||
|
class A |
|
|
|
|
|
|
|
|
|
||
|
{ int *const i; |
|
|
|
|
|
|
|
||||
|
public: |
|
|
|
|
|
|
|
|
|
||
|
|
A():i(0){} |
|
|
|
|
|
|
|
|
||
|
}; |
void f(A& a) {a.i = &::i;} |
|
|
|
|
Р |
|||||
|
|
|
|
|
|
|
|
|
|
|
||
|
int main() |
|
|
|
|
|
|
|
||||
|
{ A a; |
|
|
|
|
|
|
|
|
И |
||
|
|
|
a.f(a); |
|
|
|
|
|
|
|
||
|
} |
|
return 0; |
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
Г |
||
|
7. Закончить описание класса, добавив описание возможных компонент- |
|||||||||||
|
|
|
|
|
|
|
|
|
|
Б |
У |
|
ных функций, конструкторов и деструктора. |
|
|||||||||||
|
class Person |
|
|
|
|
а |
|
|
||||
|
{ |
|
char *name; |
// |
фамилия |
|
|
|||||
|
|
|
|
|
|
|||||||
|
|
|
int age; |
|
// |
возраст |
|
|
|
|
||
|
public : |
|
|
|
к |
|
|
|
||||
|
}; |
|
. . . |
|
|
е |
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8. Каково назначение пространства имен? |
|
||||||||||
|
9. Какое значение буд выв дено на экран? |
|
||||||||||
|
} |
|
|
|
о |
|
|
|
|
|
|
|
|
#include <iostream.h> |
|
|
|
|
|
||||||
|
namespace N |
ет |
|
|
|
|
|
|||||
|
|
|
|
и |
|
|
|
|
|
|||
|
{ int n=1; |
|
|
|
|
|
|
|||||
|
void f(int n) |
|
|
|
|
|
|
|
|
|||
|
б |
|
|
|
|
|
|
|
|
|
||
|
{ |
|
N::n++; |
|
|
|
|
|
|
|
|
|
и |
n++;л |
|
|
|
|
|
|
|
|
|||
Б |
} |
|
|
|
|
|
|
|
|
|
|
|
int main() |
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
||||
|
{ |
|
int n=1; |
|
|
|
|
|
|
|
|
|
|
|
|
N::n=2; |
|
|
|
|
|
|
|
|
|
|
|
|
f(N::n); |
|
|
|
|
|
|
|
|
n--;
cout<<n<<' '<<N::n<<endl;
}
4. НАСЛЕДОВАНИЕ
65
4.1. Наследование (производные классы)
Наследование – это одна из главных особенностей ООП. Наследование заключается в том, что один класс наследует некоторые свойства другого. Этот принцип предполагает использование базового класса, описывающего наиболее общие свойства ряда объектов. Производные классы включают в себя все черты базового класса, а также добавляют новые, характерные только для объектов данного класса. Спецификация описания производного класса имеет следую- щий синтаксис:
|
Р |
сlass имя_производного_класса : [атрибут] имя_базового_класса |
|
{тело_произв_класса} [список объектов]; |
И |
Двоеточие отделяет производный класс от базового. Как отмечалось ра- нее, ключевое слово class может быть заменено на слово struct. При этом все компоненты будут иметь атрибут public. Следует отметить, что объединение
(union) не может быть ни базовым, ни производным классом. |
|
Г |
|
Одна из особенностей порожденного класса – видимость унаследованных |
|
Б |
|
компонент базового класса. Для определения доступности компонентУ |
базового |
класса из компонент производного класса используются ключевые слова: private, protected и public (атрибуты базового кл ). Например:
class base |
|
|
|
асса |
{ private : |
private-компоненты; |
|
|
|
public : |
public-компоненты; |
|
|
|
protected : |
protected-компон нты; |
|
||
}; |
|
к |
||
|
|
|
|
|
class proizv_priv : private base { люб |
|
компоненты}; |
||
|
ые |
|
||
class proizv_publ : public base { любые компоненты}; |
||||
|
т |
|
|
|
class proizv_prot : protected base { любые компоненты}; |
Производный класс наследует атрибуты компонент базового класса в за- висимости от атрибутов базового класса следующим образом:
если базовый к асс меет атрибут public, то компоненты public и protected |
|
|
и |
базового класса нас едуются с атрибутами public и protected в производном |
|
классе. Компонентылprivate остаются private-компонентами базового класса; |
|
если базовый класс имеет атрибут protected, то компоненты public и |
|
б |
|
protected базового класса наследуются с атрибутом protected в производном |
|
классе. Компонентыи private остаются private-компонентами базового класса; |
|
если базовый класс имеет атрибут private, то компоненты public и |
|
protectedБбазового класса наследуются с атрибутами private в производном клас- |
|
се. Компоненты private остаются private-компонентами базового класса. |
|
Отмеченные типы наследования называются: внешним, защищенным и |
внутренним наследованием.
Из этого видно, что использование атрибутов private и protected ограничи- вает права доступа к компонентам базового класса через производный от базо-
66
вого класс.
Доступ к данным базового класса из производного осуществляется по имени (опуская префикс).
|
#include <iostream> |
|
|
|
|
|
|
|
|
||||
|
using namespace std; |
|
|
|
|
|
|
|
|
||||
|
#include <string.h> |
|
|
|
|
|
|
|
|
||||
|
#define n 10 |
|
|
|
|
|
// базовый класс book |
||||||
|
class book |
|
|
|
|
|
|||||||
|
{ protected: |
|
|
|
|
|
|
|
|
|
Р |
||
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
char naz[20]; |
|
|
// название книги |
|
И |
||||||
|
|
int kl; |
|
|
|
// количество страниц |
|||||||
|
|
|
|
|
|
|
|||||||
|
public: |
|
|
|
|
|
|
|
|
У |
|
||
|
|
book(char *,int); |
|
// конструктор класса book |
|
||||||||
|
|
~book(); |
|
|
// деструктор класса book |
|
|||||||
|
}; |
|
|
|
|
|
|
|
|
Г |
|
|
|
|
class avt : public book |
|
|
|
// производный класс |
||||||||
|
{ |
char fm[10]; |
|
|
|
|
Б |
|
|
|
|||
|
|
|
// фамилия автора |
|
|
||||||||
|
public: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
avt(char *,int,char *); |
// конструктор класса avt |
|
|||||||||
|
|
~avt(); |
|
|
|
// деструктор класса avt |
|
||||||
|
}; |
void see(); |
|
е |
а |
|
|
|
|
||||
|
enum razd {teh,hyd,uch}; |
к |
|
|
|
|
|
||||||
|
|
|
|
|
т |
|
|
// производный класс |
|||||
|
class rzd : public book |
|
|
|
|||||||||
|
{ |
razd rz; |
о |
|
// раздел каталога |
|
|
||||||
|
public: |
|
|
|
|
|
|
|
|
|
|||
|
и |
|
|
// конструктор класса rzd |
|
||||||||
|
}; |
|
|
|
|
||||||||
|
|
rzd(char *, int, razd); |
|
||||||||||
|
|
~rzd(); |
|
|
|
// деструктор класса rzd |
|
||||||
|
|
л |
|
|
|
|
|
|
|
|
|
|
|
|
|
void see(); |
|
|
|
|
|
|
|
|
|
||
|
б |
|
|
|
|
|
|
|
|
|
|
|
|
и |
|
|
|
|
|
|
|
|
|
|
|
||
|
book::book(char *s1,int i) : kl(i) |
|
|
|
|
|
|
||||||
Б |
{ cout << "\n работает конструктор класса |
book"; |
|
|
|||||||||
} |
strcpy(naz,s1); |
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
book::~book() |
|
|
|
|
|
|
|
|
|
|||
|
{cout << "\n работает деструктор класса |
book";} |
|
|
|||||||||
|
avt::avt(char *s1,int i,char *s2) : book(s1,i) |
|
|
|
|
||||||||
|
{ cout << "\n работает конструктор класса |
avt"; |
|
|
|||||||||
|
|
strcpy(fm,s2); |
|
|
|
|
|
|
|
|
|
67
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
avt::~avt() |
|
|
|
|
|
|
|
|
|
|
|
||
{cout << "\n работает деструктор класса |
avt";} |
|
|
|
|
||||||||
void avt::see() |
|
|
|
|
|
|
|
|
|
|
|||
{ cout<<"\nназвание : "<<naz<<"\nстраниц : "<<kl; |
|
|
|
|
|||||||||
} |
|
|
|
|
|
|
|
|
|
|
|
Р |
|
rzd::rzd(char *s1,int i,razd tp) : book(s1,i), rz(tp) |
|
|
|
||||||||||
|
|
|
|
||||||||||
{ cout << "\n работает конструктор класса |
rzd"; |
|
|
|
|
||||||||
} |
|
|
|
|
|
|
|
|
|
У |
|
||
rzd::~rzd() |
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
Г |
И |
|||||
{cout << "\n работает деструктор класса |
rzd";} |
||||||||||||
|
|
||||||||||||
void rzd::see() |
|
|
|
|
|
|
|
|
|
|
|||
{ switch(rz) |
|
|
|
|
|
а |
|
|
|
|
|||
{ case teh : cout << "\nраздел технической литературы"; break; |
|
||||||||||||
case hyd : cout << "\ nраздел художественнойБлитературы "; break; |
|||||||||||||
|
|
|
|
|
|
|
к |
|
|
|
|
||
case uch : cout << "\ nраздел учебной литер туры "; break; |
|
|
|||||||||||
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
int main() |
|
|
|
|
|
|
|
|
|
|
|
||
{avt av("Книга 1",123," автор1");//евызов конструкторов классов book и avt |
|||||||||||||
} |
|
|
|
о |
//вызов конструкторов классов book и rzd |
||||||||
rzd rz("Книга 1",123,teh); |
|
||||||||||||
av.see(); |
|
и |
т |
|
|
|
|
|
|
||||
rz.see(); |
|
|
|
|
|
|
|
||||||
л |
|
|
|
|
|
|
|
||||||
На приведенном н же примере показаны различные способы доступа к |
|||||||||||||
|
б |
|
|
|
|
|
|
|
|
|
|
||
компонентам классов иерархической структуры, в которой классы A, B, C - ба- |
|||||||||||||
зовые для класса D, а к асс D, в свою очередь, является базовым для класса Е. |
|||||||||||||
#include <iostream> |
|
|
|
|
|
|
|
|
|
||||
Б |
|
|
|
|
|
|
|
|
|
|
|
|
|
using namespace std; |
|
|
|
|
|
|
|
|
|
||||
classиA |
|
|
|
|
|
|
|
|
|
|
|||
{ private: |
a_1(){cout<<"private-функция a_1"<< endl;} |
|
|
|
|||||||||
protected: a_2(){cout<<"protected-функция a_2"<< endl;} |
|
|
|||||||||||
public: |
|
a_3(){cout<<"public-функция a_3"<< endl;} |
|
|
|
}; class B
{private: b_1(){cout<<"private-функция b_1"<< endl;} protected: b_2(){cout<<"protected-функция b_2"<< endl;}
68
public: b_3(){cout<<"public-функция b_3"<< endl;}
}; class C
{private: c_1(){cout<<"private-функция c_1"<< endl;} protected: c_2(){cout<<"protected-функция c_2"<< endl;} public: c_3(){cout<<"public-функция c_3"<< endl;}
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class D : public A, protected B, private C |
|
|
|
||||||||||
|
{ private: |
d_1(){cout<<"private-функция d_1"<< endl;} |
|
|||||||||||
|
protected: d_2(){cout<<"protected-функция d_2"<< endl;} |
|||||||||||||
|
public: |
d_3(); |
|
|
|
|
|
|
|
Р |
||||
|
}; |
|
|
|
|
|
|
|
|
|
|
|
||
|
D:: d_3() |
|
|
|
|
|
|
У |
||||||
|
{ |
d_1(); |
|
|
|
|
|
Г |
И |
|||||
|
// |
d_2(); |
|
|
|
|
|
|||||||
|
a_1(); |
//'a_1' cannot access private member declared in class 'A' |
||||||||||||
|
|
a_2(); |
|
|
|
|
|
|
|
|
|
|||
|
|
a_3(); |
|
|
|
|
а |
|
|
|
||||
|
// |
b_1(); |
//'b_1' cannot access private member declared in class 'B' |
|||||||||||
|
|
b_2(); |
|
|
|
к |
Б |
|
|
|
||||
|
|
b_3(); |
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
||||
|
// |
c_1(); |
//'c_1' cannot access private member declared in class 'C' |
|||||||||||
|
|
c_2(); |
|
|
е |
|
|
|
|
|
||||
|
|
c_3(); |
|
|
|
|
|
|
|
|||||
|
}; |
return 0; |
о |
|
|
|
|
|
||||||
|
} |
|
|
|
|
т |
|
|
|
|
|
|
||
|
class E : public D |
|
|
|
|
|
|
|||||||
|
|
|
|
и |
|
|
|
|
|
|
||||
|
{ public: e |
1(); |
|
|
|
|
|
|
||||||
|
E:: e 1() |
|
|
|
|
|
|
|
|
|
||||
|
б |
|
//'a_1' cannot access private member declared in class 'A' |
|||||||||||
|
{// |
a |
1(); |
|||||||||||
и |
лa 2(); |
|
|
|
|
|
|
|
|
|
||||
Б |
|
a |
3(); |
|
|
|
|
|
|
|
|
|
||
// |
b |
1(); |
// b_1 cannot access private member declared in class 'B' |
|||||||||||
|
||||||||||||||
|
|
b_2(); |
|
|
|
|
|
|
|
|
|
|||
|
|
b_3(); |
|
|
|
|
|
|
|
|
|
|||
|
// |
c_1(); |
// c_1 cannot access private member declared in class 'C' |
|||||||||||
|
// |
c_2(); |
// c_2 cannot access private member declared in class 'C' |
//c_3(); // c_3 cannot access private member declared in class 'C' return 0;
}
int main() { A a;
69