
- •1.Понятие о дружественности.
- •2.Динамическое распределение памяти.
- •3.Инкапсуляция и полиморфизм.
- •4.Наследование классов.
- •5.Виртуальные функции.
- •6.Восходящий подход программирования.
- •7.Нисходящий подход. Иерархический и операционный подходы.
- •8.Нисходящий подход. Смешанный подход.
- •9.Понятие о модульном программировании.
- •10.Прочность модулей.
- •11.Сцепление модулей.
- •12.Отладка программ на языке высокого уровня.
- •13.Тестирование в процессе создания программы.
- •14.Систематическое тестирование.
- •15.Стрессовое тестирование.
- •16.Автоматизация тестирования.
- •17.Тестирование белого и черного ящиков. Тестирование пользователями.
- •18.Верификация программного обеспечения.
- •19.Валидация программного обеспечения.
- •20.Система факторов качества по с позиции пользователя.
- •21.Система факторов качества по с позиции разработчика.
Ответы по проге
1.Понятие о дружественности.
При помощи специального спецификатора доступа можно указать, имеют ли функции, не являющиеся элементами данного класса, доступ к его элементам. Может возникнуть ситуация, когда нужно обеспечить определенной функцие или классу доступ к элементам данного класса, объявленным при помощи private или protected. Это делается при помощи ключевого слова friend:
friend class A
friend void B(float c)
Правила:
1)Если А объявил Б другом, это не значит, что Б объявил другом А.
2)Если А объявил Б другом, то наследники Б не получают автоматически доступ к А.
3)Если А объявил Б другом, то наследники А не будут автоматически признавать другом Б.
2.Динамическое распределение памяти.
Классы памяти:
-автоматические
-регистровые
-статические
-внешние
Распределения:
-статическое
-динамическое
В C++ существуют специальные операции для управления динамическим распределением памяти: new и delete – для простых переменных и new[] и delete[] – для массивов. Также сохранены стандартные функции C – malloc(), calloc(), realloc(), free().
int *A;
A=new int;
*A=125;
cout<<*A;
delete A;
A=new int[100];
delete [] A;
А также для простых переменных: int *A=new int(456);
Классы могут определять свои собственные операции new и delete(new[] и delete[]). Синтаксис их перегрузки не отличается от обычной перегрузки операций:
void *A:: operator new(…)
{…};
Если new или delete вызывается для представителя класса, то одновременно с ними вызывается конструктор или деструктор, соответственно. Для переменных, память под которые выделена таким образом, конструктор не выделяет, а деструктор не освобождает память, так как это делают new и delete.
3.Инкапсуляция и полиморфизм.
Под инкапсуляцией понимают наличие механизма, позволяющего объединять некоторым скрытым от пользователя образом данные и функции для обработки этих данных. (Как пример: предположим, что мы написали игру и нам совсем не хочется, чтобы какой-то левый ум покопался в нашем коде, что-то там искал или пытался понять как мы это сделали. Поэтому используем специальные механизмы, не позволяющие пользователю лезть в наш код, то есть – если хочешь, пожалуйста, пользуйся, играй в нашу игру, но тебе для этого не надо знать, как мы ее делали. Как раз тот факт, что существуют такие механизмы и позволяет нам говорить о понятии инкапсуляции.)
Под полиморфизмом понимается способность некоторых механизмов (например, функций) по-разному реагировать на внешне одинаковый запрос. (Пример: виртуальные функции, перегрузка функций.)
4.Наследование классов.
C++ позволяет классу наследовать элементы данных и элементы-функции одного или нескольких других классов, новый класс называют производным (сын), класс, элементы которого наследуются, называется базовым (отец). Производный класс, в свою очередь, может быть базовым для другого класса.
Наследование относится к базовым принципам объектно-ориентированного программирования (инкапсуляция, полиморфизм, наследование).
Производный класс может переопределить некоторые функции-элементы базового, наследуя, тем не менее, основной объем свойств базового класса.
class A{…}; class B: ключ A {…};
Ключ, находящийся в заголовке класса насоедника может быть private, public или protected. Если его нет, то по умолчанию используется private для классов и public для структур. Этот ключ оказывает влияние только на доступ к элементам отца через представитель сына, при этом он не оказывает влияния на доступ к элементам отца из тела функции класса сына. Для определения можно или нельзя через представитель сына обратиться к унаследованным элементам отца используется более жёсткий спецификатор из ключа, стоящего в теле отца, и ключа, стоящего в заголовке сына. (То есть: при public, стоящем в заголовке сына мы можем из, например, функции main, используя представитель класса сына обратиться к public элементам отца, также мы можем обращаться к public и protected элементам отца из тела сына; при private мы не можем обращаться к элементам отца ниоткуда; и наконец, при protected, мы можем обратиться к public и protected элементам отца из тела класса сына, а также при таком наследовании все public элементы отца наследуются сыном со сменой спецификатора на protected, то есть будующие наследники от уже существующего, обращаясь к этим элементам, будут обращаться к ним как к protected, а не как к public). (И да, это полная ***а ).
При наследовании не происходит наследования конструкторов и деструкторов отца, таким образом, чтобы использовать конструктор отца, его необходимо вызвать при создании конструктора сына, причем он будет вызываться в списке инициализации конструктора сына:
class A {…A(параметры);…}; class B: ключ A {... B(параметры): A(параметры);…}
С++ допускает сложное наследование – одновременное наследование от нескольких классов:
class C: ключ A, ключ B {…};
При этом может оказаться так, что класс унаследует несколько элементов одного и того же класса (То есть: например, класс B – наследник класса A, а класс C – наследник классов A и B. Следовательно класс C унаследует элементы класса А, элементы класса В и снова элементы класса А, потому что их наследовал класс В).