Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
0495976_C19D7_shpory_s.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
1.82 Mб
Скачать

3. Наследовние

Наследование (inheritance) - это процесс, посредством которого один объект может приобретать свойства другого. Точнее, объект может наследовать основные свойства другого объекта и добавлять к ним черты, характерные только для него. Наследование является важным, поскольку оно позволяет поддерживать концепцию иерархии классов (hierarchical classification). Применение иерархии классов делает управляемыми большие потоки информации. Например, подумайте об описании жилого дома. Дом - это часть общего класса, называемого строением. С другой стороны, строение - это часть более общего класса - конструкции, который является частью ещё более общего класса объектов, который можно назвать созданием рук человека. В каждом случае порождённый класс наследует все, связанные с родителем, качества и добавляет к ним свои собственные определяющие характеристики. Без использования иерархии классов, для каждого объекта пришлось бы задать все характеристики, которые бы исчерпывающи его определяли. Однако при использовании наследования можно описать объект путём определения того общего класса (или классов), к которому он относится, с теми специальными чертами, которые делают объект уникальным. Наследование играет очень важную роль в OOP.

22.Использование new и delete на примере динамических массивов, стеков, очередей.

Операции new[] и delete[] позволяют создавать и удалять динамические массивы, поддерживая при этом иллюзию произвольной размерности. Деятельность по организации динамического массива требует дополнительного внимания, которое окупается важным преимуществом: характеристики массива (операнды операции new) могут не быть константными выражениями. Это позволяет создавать многомерные динамические массивы произвольной конфигурации. Следующий пример иллюстрирует работу с динамическими массивами.

#include <iostream.h>

int fdArr(int **, int, int);

int fdArr(int ***, int, int, int);

// Одноимённые функции. Различаются списками списками параметров.

// Это так называемые перегруженные функции. О них позже.

void main()

{

int i, j;

/* Переменные (!) для описания характеристик массивов.*/

int dim1 = 5, dim2 = 5, dim3 = 10, wDim = dim2;

/*

Организация двумерного динамического массива производится в два этапа.

Сначала создаётся одномерный массив указателей, а затем каждому элементу

этого массива присваивается адрес одномерного массива. Для характеристик

размеров массивов не требуется константных выражений.

*/

int **pArr = new int*[dim1];

for (i = 0; i < dim1; i++) pArr[i] = new int[dim2];

pArr[3][3] = 100;

cout << pArr[3][3] << endl;

fdArr(pArr,3,3);

/*

Последовательное уничтожение двумерного массива…

*/

for (i = 0; i < dim1; i++) delete[]pArr[i];

delete[]pArr;

/*

Организация двумерного "треугольного" динамического массива. Сначала

создаётся одномерный массив указателей, а затем каждому элементу этого

массива присваивается адрес одномерного массива. При этом размер

(количество элементов) каждого нового массива на единицу меньше

размера предыдущего. Заключённая в квадратные скобки переменная в

описателе массива, которая, в данном контексте, является операндом

операции new, позволяет легко сделать это.

*/

int **pXArr = new int*[dim1];

for (i = 0; i < dim1; i++, wDim--) pXArr[i] = new int[wDim];

pXArr[3][3] = 100;

cout << pArr[3][3] << endl;

fdArr(pXArr,3,3);

/*

Последовательное уничтожение двумерного массива треугольной конфигурации…

*/

for (i = 0; i < dim1; i++) delete[]pXArr[i];

delete[]pXArr;

/*

Создание и уничтожение трёхмерного массива требует дополнительной итерации.

Однако здесь также нет ничего принципиально нового.

*/

int ***ppArr;

ppArr = new int**[dim1];

for (i = 0; i < dim1; i++) ppArr[i] = new int*[dim2];

for (i = 0; i < dim1; i++)

{

for (j = 0; j < dim2; j++) ppArr[i][j] = new int[dim3];

}

ppArr[1][2][3] = 750; cout << ppArr[1][2][3] << endl; fdArr(ppArr,1,2,3);

for (i = 0; i < dim1; i++)

{

for (j = 0; j < dim2; j++) delete[]ppArr[i][j];

}

for (i = 0; i < dim1; i++) delete[]ppArr[i];

delete[] ppArr;

}

int fdArr(int **pKey, int index1, int index2)

{

cout << pKey[index1][index2] << endl;

}

int fdArr(int ***pKey, int index1, int index2, int index3)

{

cout << pKey[index1][index2][index3] << endl;

}

23)Возможны ситуации, когда для получения доступа к закрытым членам класса вам понадобится функция, не являющаяся членом этого класса. Для достижения этой цели в C++ поддерживаются дружественные функции (friend functions). Дружественные функции не являются членами класса, но тем не менее имеют доступ к его закрытым элементам.

Дружественная функция задается так же, как обычная, не являющаяся членом класса, функция. Однако в объявление класса, для которого функция будет дружественной, необходимо включить ее прототип, перед которым ставится ключевое слово friend. Чтобы понять, как работает дружественная функция, рассмотрим следующую короткую программу:

#include <iostream.h>

int i,j;

class matrix

{

int Row,Col;

double **Value;

public:matrix(int row,int col);

matrix(matrix &m);

~matrix();

int GetRow();

int GetCol();

double &operator()(int row,int col);

friend matrix operator+(matrix &m1,matrix &m2);

friend matrix operator*(matrix &m1,matrix &m2);

friend matrix operator-(matrix &m1,matrix &m2);

matrix operator=(matrix &m);

friend istream &operator>>(istream &istr,matrix &m);

friend ostream &operator<<(ostream &ostr,matrix &m);

};

24.Использование указателей на методы класса.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]