Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛЕКЦИИ Программирование и основы алгоритмизации...doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.5 Mб
Скачать

Композиция классов

Суть композиции классов состоит в том, что объекты одних классов используются как элементы других классов.

Пример: служащий с датами рождения и приёма на работу.

//------------------------------------------------------------------------------

class date{

public:

date(int=1, int=1, int=1980); //конструктор с умолчанием

void print() const;

private:

int m, d, y;

};

//-------------------------------------------------------------------------------

class employee {

public:

employee (char*, char*, int, int, int, int, int, int);

void print() const;

private:

date bdat; // дата рождения

date hdat; // дата приема на работу

};

//---------------------------------------------------------------------------------

employee:: employee(char* f, char* l, int bm, int bd, int by,

int hm, int hd, int hy)

:bdat(bm, bd, by), hdat(hm, hd, hy)

{------------}

//----------------------------------------------------------------------------------

void main()

{ employee e(“Петров”,”Иван”, 7, 24, 1979, 6, 11, 2000);

----------------------------------------

}

//---------------------------------------------------------------------------------

Программа создает объект e класса employee, задает начальные значения данным-элементам. Конструктор employee принимает 8 аргументов. Инициализаторы элементов (отделены через ‘:’) указывают, что аргументы employee передаются конструкторам объектов-элементов.

Если инициализаторы элементов не заданы, будет автоматически вызван конструктор (с умолчанием) объекта-элемента. Затем значения, установленные конструктором с умолчанием, могут быть изменены с помощью функций записи “set”. Если же в этом случае не предусмотрен конструктор с умолчанием, то появится ошибка – объект-элемент не будет инициализирован.

Дружественные функции класса

Определяются вне области действия этого класса, но имеют право доступа к закрытым private и защищенным protected элементам данного класса.

//-------------------------------------------------------------------

#include <iostream.h>

class count {

friend void setx(count&, int); // объявление дружественной функции

public:

count() {x=0;} //конструктор

void print() const { cout<<x<<endl; }

private:

int x;

};

//Определение дружественной функции

void setx(count& c, int v)

{ c.x=v; } //доступ к x – через ссылку c

//--------------------------------------------------------

void main()

{ count ob;

ob.print(); //0

setx(ob, 10);

ob.print(); //10

}

//----------------------------------------------------------------------

Дружественный класс

class BinSTree; //предварительное объявление класса

class TreeNode {

friend class BinSTree;

----------------------

-------------------

};

Дружественный класс BinSTree имеет доступ через свои функции-элементы к функциям-элементам класса TreeNode.

Использование указателя this

Каждый объект сопровождается указателем на самого себя. this – это неявный аргумент во всех ссылках на элементы внутри этого объекта. this можно использовать явно, например, для определения собственного адреса объекта.

1) Указатель this неявно используется в функциях-элементах класса для ссылки как на данные-элементы, так и на функции-элементы объекта. Если функция-элемент – неконстантная, то this – это константный указатель на неконстантный объект, а если функция-элемент – константная, то this – константный указатель на константный объект. this используется только внутри функций-элементов класса. Каждая функция-элемент имеет доступ к указателю this на объект, для которого эта функция вызвана.

Пример неявного и явного использования this для ссылки на элементы объекта.

//-----------------------------------------------------------------

#include <iostream.h>

class test {

public:

test(int=0);

void print() const;

private:

int x;

};

//-------------------------------------------

test::test(int a) { x=a; }

//---------------------------------------------

void test::print() const

{ cout<<x<<endl //неявное

<<this->x<<endl //явное

<<(*this).x<<endl; //явное

}

//--------------------------------------------

void main()

{ test a(12);

a.print(); //12

//12

//12

}

//--------------------------------------------------------------------------

2) Сцепленные вызовы функций-элементов

//---------------------------------------------------

#include <iostream.h>

class time {

public:

time(int=0, int=0, int=0);

time& seth(int); //установка часа

time& setm(int); //установка минут

time& sets(int); //установка секунд

-----------------------

private:

int h, m, s;

};

//----------------------------------------------------

time& time::seth(int hs)

{ h=(hs>=0&&hs<24)?hs:0;

return *this;

}

//-----------------------------------------------------

void main()

{time t;

t.seth(10).setm(15).sets(20); //выполнение слева-направо

t.printtime(); //10:15:20

}

//------------------------------------------------------

Каждая из функций-элементов - seth(), setm(), sets() – возвращает *this с типом возврата time&, что дает возможность сцепленных вызовов функций-элементов класса time. Операция (.) имеет ассоциативность слева-направо, так что сначала выполняется t.seth(10), а затем возвращает ссылку на объект t как значение вызова этой функции.