- •Оглавление
- •1. Спецификация const для данных. Назначение.
- •2. Спецификация inline для функций. Назначение.
- •4. Ссылки. Назначение, обращение к данным по ссылке, использование ссылок для параметров функции и возвращаемого значения.
- •5. Динамическое создание и уничтожение объектов. Можно ли операции new и delete использовать вместе с malloc и free?
- •6. Динамическое создание и уничтожение массивов объектов.
- •8. Использование операции :: для доступа к элементам класса и глобальным функциям и переменным
- •9. Спецификации const для методов, не изменяющих объект. Спецификация mutable для элементов данных.
- •10. Дружественные функции и классы.
- •11. Статические переменные класса. Определение и инициализация.
- •12. Статические методы класса.
- •13. Указатель this. Назначение.
- •14. Конструктор: назначение, объявление (синтаксис), момент выполнения.
- •15. Конструктор: инициализация базовых классов и данных объекта через список инициализации в конструкторе.
- •16. Конструктор по умолчанию: объявление (синтаксис), назначение.
- •17. Конструктор копий: объявление (синтаксис), назначение.
- •18. Деструктор: назначение, объявление (синтаксис), момент выполнения.
- •19. Констукторы-преобразователи и операции для преобразования, способ вызова. Спецификация explicit для конструкторов-преобразователей.
- •20. Шаблоны функций: определение (синтаксис), назначение. Как вызвать функцию-шаблон?
- •21. Шаблоны классов (параметризация): определение (синтаксис), назначение. Как создать объект шаблонного класса?
- •22. Специализация шаблонов.
- •23. Библиотека stl. Общая характеристика.
- •24. Перегрузка функций и методов, основные правила связывания.
- •25. Правила перегрузки операций
- •26. Формат перегрузки унарных и бинарных операций как методов и [дружественных] функций.
- •28. Перегрузка операций присваивания: назначение, объявление (синтаксис), действия выполняемые в методе.
- •29. Перегрузка операций [] и () : назначение, объявление (синтаксис).
- •31. Перегрузка операций new и delete в классе: назначение, объявление (синтаксис).
- •32. Исключительные ситуации: назначение и стандартные искл. Ситуации (кроме stl).
- •33. Исключительные ситуации: порождение и перехват (синтаксис).
- •34. Исключительные ситуации: спецификация порождаемых исключительных ситуаций в заголовке функции.
- •36. Чисто виртуальные функции и абстрактные классы.
- •37. Простое наследование: определение, синтаксис. Порядок выполнения конструкторов и деструкторов. Вызов методов, переопределенных в производном классе, из базового класса.
- •39. Операция typeid. Rtti.
- •40. Операция безопасного преобразования данных const_cast. Назначение, синтаксис вызова.
- •41. Операция безопасного преобразования данных static_cast. Назначение, синтаксис вызова.
- •42.Операция безопасного преобразования данных dynamic_cast. Назначение, синтаксис вызова.
- •43. Операция безопасного преобразования данных reinterpret_cast. Назначение, синтаксис вызова.
- •44. Пространства имен: назначение, определение (синтаксис), варианты использования имен из namespace в своей программе.
- •45. Какие методы должны быть определены в классе с динамическим выделением памяти для некоторых элементов данных?
- •46. Сложность программного обеспечения.
- •47. Пять свойств сложной системы.
- •48. Основные методы при создании сложных систем.
- •49. Основные положения оо подхода.
- •50. Концепции оо подхода: Абстрагирование.
- •51. Концепции оо подхода: Ограничение доступа.
- •52. Концепции оо подхода: Модульность
- •53. Концепции оо подхода: Иерархия.
- •54. Концепции оо подхода: Типизация.
- •55. Концепции оо подхода: Параллелизм.
- •56. Концепции оо подхода: Устойчивость (сохраняемость).
- •57. Объекты в ооп: Определение объекта.
- •58. Объекты в ооп: Состояние.
- •59. Объекты в ооп: Поведение. Операции.
- •60. Объекты в ооп: Уникальность (идентичность).
- •61. Объекты в ооп: Отношения между объектами.
- •62. Классы в ооп: Понятие класса, связь между объектами и классами.
- •63. Отношения между классами: Ассоциации.
- •64. Отношения между классами: Наследование.
- •65. Отношения между классами: Агрегация.
- •66. Отношения между классами: Использование.
- •67. Отношения между классами: Конкретизация (параметризованные классы).
- •68. Отношения между классами: Метаклассы.
- •69. Паттерны проектирования: Абстрактная фабрика.
- •70. Паттерны проектирования: Одиночка.
- •71. Паттерны проектирования: Прототип (виртуальный конструктор).
- •72. Паттерны проектирования: Адаптер.
- •73. Паттерны проектирования: Заместитель.
- •74. Паттерны проектирования: Компоновщик.
- •75. Паттерны проектирования: Декоратор.
- •76. Паттерны проектирования: Итератор.
- •77. Паттерны проектирования: Шаблонный метод.
1. Спецификация const для данных. Назначение.
Квалификатор const позволяет создавать типизированные константы, с ограниченной областью видимости в отличие от констант, определенных #define. Задать значение константе можно только при создании.
const int size=100;
int a[size];
const double pi=3.14159265358979323846;
Также этот квалификатор используется для указания, что параметр не меняется внутри функции.
char *strcpy(char *dst, const char *src);
Самый простой случай — константные данные. Возможно несколько вариантов записи: const int i(1);
int const j(1);
int const k=1;
Все они правильные и делают одно и тоже — создают переменную, значение которой изменить нельзя.
При использовании const с указателями, действие модификатора может распространяться либо на значение указателя, либо на данные на которые указывает указатель. Работает (const относится к данным): const char * a = "a";
a="b";
Тоже самое и тоже работает: char const * a = "a";
a="b";
Существует мнемоническое правило, позволяющее легко запомнить, к чему относится const. Надо провести черту через "*", если const слева, то оно относится к значению данных; если справа — к значению указателя. Ну и конечно, const можно написать дважды: const char * const s = "data"
2. Спецификация inline для функций. Назначение.
Функция, определенная с помощью спецификатора inline становится встраиваемой, т.е. её код подставляется в точку вызова. При этом устраняются все недостатки, свойственные макроопределениям. Время работы программы уменьшается за счет операций сохранения/восстановления регистров и передачи управления, но размер программы увеличивается. Спецификатор inline носит рекомендательный характер, для больших функций компилятор генерирует обычный вызов. Тело встраиваемой функции определяется в заголовочном файле.
inline int max(int x, int y)
{ return x>y?x:y;
}
Макроопределение #define max(x,y) ((x)>(y)?(x):(y)) работает для любых типов данных. Чтобы функция max работала так же, её нужно определить как шаблон:
template <typename T>
inline T max(T x, T y)
{ return x>y?x:y;
}
3. Модульность в С++. Что пишется в файле .h, что в файле .cpp? Как использовать модуль, разбитый на эти 2 файла, в своих программах?
В языке C++ модулями являются раздельно компилируемые файлы. Интерфейсная часть модуля помещается в заголовочный файл с расширением .h (может быть общим для нескольких модулей), а реализация помещается в файл с расширением .cpp. Заголовочный файл подключается к файлу с реализацией и в модули-клиенты с помощью директивы препроцессора #include. Такой подход строится исключительно на соглашении и не является строгим требованием самого языка. Пример программы, состоящей из двух модулей.
Файл module1.h:
struct point {
double x,y;
double len();
};
extern point p1;
Файл module1.cpp:
#include "module1.h"
#include <math.h>
double point::len()
{ return sqrt(x*x+y*y);
}
point p1;
Файл module2.cpp:
#include "module1.h"
...
int main()
{ point a=p1;
cout<<a.len()<<"\n";
...
}
Правильное разделение программы на модули является почти такой же сложной задачей, как выбор правильного набора абстракций. Поскольку в начале работы над проектом решения могут быть неясными, декомпозиция на модули может вызвать затруднения. Для хорошо известных приложений этот процесс можно стандартизовать, но для новых задач задача может быть очень трудной.
Для небольших задач допустимо описание всех классов и объектов в одном модуле. Однако для большинства программ лучшим решением будет сгруппировать в отдельный модуль логически связанные классы и объекты, оставив открытыми только те элементы, которые необходимо видеть другим модулям. Конечной целью декомпозиции программы на модули является снижение затрат на программирование за счет независимой разработки и тестирования. Структура модуля должна быть достаточно простой для восприятия; реализация каждого модуля не должна зависеть от реализации других модулей; должны быть приняты меры для облегчения процесса внесения изменений там, где они наиболее вероятны.
Если изменяется реализация, то заново компилируется только данный модуль, и программа перекомпонуется. Перекомпиляция интерфейсной части модуля, напротив, более трудоемка, так как приходится перекомпилировать все модули, связанные с данным, для очень больших программ могут потребоваться многие часы на перекомпиляцию. Поэтому следует стремиться к тому, чтобы интерфейсная часть модулей была возможно более узкой. Таким образом, программист должен находить баланс между двумя противоположными тенденциями: стремлением скрыть информацию и необходимостью обеспечения видимости тех или иных абстракций в нескольких модулях.
