Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь 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; просмотров: 185; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.217.39 (0.009 с.) |