Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Член-данные класса – объекты другого класса: агрегированные классы.Содержание книги
Поиск на нашем сайте
Член-данное какого-либо класса может быть переменной, указателем или ссылкой, тип которых – другой известный на данный момент класс. Такой класс называется агрегированным. Рассмотрим пример.
class A { int x, y; public: A(int xx = 0) {x = y = xx;} // конструктор с аргументом по умолчанию A(int xx, int yy) {x = xx; y = yy;} void Print() {cout << ’\n’ << x << ’ ‘ << y;} int Getx() {return x;} int Gety() {return y;} };
class B // агрегированный класс { A a; int z; public: B() {z = 0;} B(int, int, int); void Print(); … };
Главное правило при использовании объектов другого класса: конструктор использующего класса отвечает за инициалаизацию член-данных используемых классов! В нашем примере – это конструктор класса B. И этот конструктор должен быть задан так:
B:: B(int, int, int): a(b, c), z(d) { }
список инизиализации
Собственные член-данные можно инициализировать и внутри { }:
B:: B(int b, int c, int d): a(b, c) {z = d;}
Заметим, что если в классе A есть конструктор по умолчанию, то он будет работать, даже если он явно не указан в списке инициализации конструктора класса B. В нашем примере при работе конструктора B() будет работать конструктор A(int xx = 0). Порядок работы конструкторов при объявлении объекта класса B: сначала в A, затем в B. Несколько сложнее выглядит конструктор агрегированного класса, если член-данное в нем – указатель на объект другого класса, и он определяет массив. В этом случае конструктор должен брать память в динамической области и инициализировать элементы массива. Списком инициализации здесь не обойтись. Рассмотрим на примере, как в этом случае можно определить конструктор агрегированного класса. Пусть имеется класс Array – числовой массив. Используем его для определения класса числовая матрица Matrix:
class Matrix {Array * a; int m, n; public: Matrix(int m1, int n1, int t = 0); // t!= 0 – создание элементов матрицы случайным образом Array &operator [ ](int i) // возвращает ссылку на i-ую строку матрицы {if (i < 0 || i >= m) {cout << ”Такой строки нет!”); exit(0);} return a[i]; } void Show(); // вывод матрицы ... };
Matrix:: Matrix(int m1, int n1, int t) {a = new Array[m = m1]; // Так как в этом случае используется только конструктор по умолчанию // класса Array (см п.10), то определить строки длиной n можно таким образом:
n = n1; for(int i = 0; i < m; i++) {Array b(n, t); // создается массив – строка матрицы, t – инициализация a[i] = b; // работает перегруженная операция ‘=’ класса Array } }
Пример использования:
void main() {Matrix c(4, 5, 1); c.Show(); c[1][1] = 100; // Работают две перегруженные операции [ ]: первая – в классе Matrix, вторая – в классе Array cout << c[0]; // вывод строки с номером 0 операцией потокового вывода, определенной для класса Array }
Вернемся к классам A и B. Разберемся, как в классе B можно использовать член-данные х и у из класса A. Определим функцию вывода в классе B:
void B:: Print() {cout << ’\n’ << a.x << ‘ ’ << a.y << ’ ‘ << z;} (1)
Так нельзя! a.x, a.y – член-данные из части private класса A Способы выхода из положения: 1) использовать a.x и a.y в член-функциях класса B непосредственно станет возможным (см. (1)), если объявить класс B дружественным классу A.
class B; class A {friend class B; ... };
2) использовать x и y через член-функции класса A из части public:
void B:: Print() {a.Print(); cout << ’ ‘ << z;}
3) в некоторых случаях приходится специально задавать функции, которые возвращают то или иное значение из части private используемого класса. Например, в классе A – функции Getx(), Gety(). Функция Print() в классе B в этом случае может быть определена таким образом
void B:: Print() {cout << ’\n’ << a.Getx() << ’ ‘ << a.Gety() << ’ ‘ << z;}
Пример использования агрегированных классов.
void main() { A a1, a2(7, 8); // работают оба конструктора класса A B b1; // работают конструкторы по умолчанию классов A и B: // b1.a.x = b1.a.y = b1.z = 0; B b2(1, 2, 3); // работают конструкторы с аргументом сначала A, // потом B: b2.a.x = 1; b2.a.y = 2; b2.z = 3; a1.Print(); a2.Print(); // функция Print() класса A b1.Print(); b2.Print(); // функция Print() класса B }
Рассмотрим графический пример. Зададим 3 класса: прямоугольник Bar, круг Circ, круг на прямоугольнике CircOnBar.
const int CF = 7; class Bar { int h, w, x, y; public: Bar(int hh, int ww, int xx, int yy) {h = hh; w = ww; x = xx; y = yy;} void Show(int c) { }; };
class Circ {int r, x, y; public: Circ(int rr, int xx, int yy) {r = rr; x = xx; y = yy;} void Show(int c) { } };
class CircOnBar { Bar b; Circ c; public: CircOnBar(int h, int w, int x, int y, int r): b(h, w, x, y), c(r, x + w / 2, y - r) { } void Show(int cb, int cc) {b.Show(cb); c.Show(cc);} };
void main()
{ int x = 20, i, dx = 100; // Определяем массив агрегированных объектов - CircOnBar CircOnBar bc[3] = {CircOnBar(100, 50, x = x + dx, 100, 30), CircOnBar(100, 50, x = x + dx, 100, 30), CircOnBar(100, 50, x + dx, 100, 30)}; for(i = 0; i < 3; i++) bc[i].Show(2 * i + 1, 2 *i + 2); //Выводим их на экран CircOnBar * pbc = new CircOnBar(50, 50, 500, 300, 50); // Объект в динамической памяти: pbc –> Show(4, 12); delete pbc; }
|
||||||
Последнее изменение этой страницы: 2021-12-07; просмотров: 143; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.226.166.207 (0.009 с.) |