Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Наследование. Конструкторы и деструкторы.





q Новые классы образуются при помощи старых, заимствуя все поля методы и реализуя некоторую новую функциональность.

q Классы, находящиеся в вершине иерархии, объединяют в себе некоторое количество свойств, общих для всей иерархии.

q Постепенно, спускаясь по иерархии вниз, мы добиваемся все большей детализации.

Для порождения нового класса от существующего применяется следующая конструкция:

class <имя класса>: <модификатор> <имя базового класса> { <описание членов класса> };

 

Конструкторы не наследуются, поэтому производный класс должен иметь собственные конструкторы. Порядок вызова конструкторов определяется приведенными ниже правилами.

Если в конструкторе производного класса явный вызов конструктора базового класса отсутствует, автоматически вызывается конструктор базового класса по умолчанию (то есть тот, который можно вызвать без параметров).

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

Если конструктор базового класса требует указания параметров, он должен быть явным образом вызван в конструкторе производного класса в списке инициализации.

Операция присваивания не наследуется, поэтому ее необходимо переписывать явно в каждом выведенном классе.

Правила для деструкторов:

q Деструкторы не наследуются, и если программист не описал в производном классе деструктор, он формируется по умолчанию и вызывает деструкторы всех базовых классов.

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

q Для иерархии классов, состоящей из нескольких уровней, деструкторы вызываются в порядке, строго обратном вызову конструкторов, сначала вызывается деструктор класса, затем – деструкторы элементов класса, а потом деструктор базового класса.

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

(из интернета с примером)

Поскольку конструкторы не наследуются, при создании производного класса наследуемые им данные-члены должны инициализироваться конструктором базового класса. Конструктор базового класса вызывается автоматически и выполняется до конструктора производного класса. Если наследуется несколько базовых классов, то их конструкторы выполняются в той последовательности, в которой перечислены базовые классы в определении производного класса. Конструктор производного класса вызывается по окончании работы конструкторов базовых классов. Параметры конструктора базового класса указываются в определении конструктора производного класса. Таким образом происходит передача аргументов от конструктора производного класса конструктору базового класса.


Пример

class Basis
{
public:
Basis(int x, int y)
{
a = x;
b = y;
}
private:
int a, b;
};

class Inherit: public Basis
{
public:
Inherit(int x, int y, int s)
: Basis (x, y)
{
sum = s;
}
private:
int sum;
};

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

Объекты класса конструируются снизу вверх: сначала базовый, потом компоненты-объекты (если они имеются), а потом сам производный класс. Т.о. объект производного класса содержит в качестве подобъекта объект базового класса.

Уничтожаются объекты в обратном порядке: сначала производный, потом его компоненты-объекты, а потом базовый объект.

Как мы знаем, объект уничтожается при завершении программы или при выходе из области действия определения объектов и эти действия выполняет деструктор. Статус деструктора по умолчанию public. Деструкторы не наследуется, поэтому даже при отсутствии в производном классе деструктора, он не передается из базового, а формируется компилятором как умалчиваемый. Классы, входящие в иерархию, должны иметь в своем распоряжении виртуальные деструкторы. Деструкторы могут переопределяться, но не перегружаться.

В любом классе могут быть в качестве компонентов определены другие классы. В этих классах могут быть свои деструкторы, которые при уничтожении объекта охватывающего (внешнего) класса выполняются после деструктора охватывающего класса. Деструкторы базовых классов выполняются в порядке, обратном перечислению классов в определении производного класса. Таким образом, порядок уничтожения объекта противоположен по отношению к порядку его конструирования.



Пример.

// Определение класса базового класса ТОЧКА и производного класса ПЯТНО.
class Point // Определение класса ТОЧКА
{
public:
Point(int x1 = 0, int y1 = 0);
int &getx(void);
int &gety(void);
void show(void);
void move(int x1 = 0, int y1 = 0);
protected:
int x, y;
private:
void hide(void);
};

class Spot: public Point // Определение класса ПЯТНО
{
public:
Spot(int, int, int);
void show(void);
void hide(void);
void move(int, int);
void change(int); // изменить размер
protected:
int r; // радиус
int vis; // признак видимости
int tag; // признак сохранения видимого образа объекта в памяти
spot *pspot; // указатель на область памяти для видимого образа
};

// Определение функций - членов класса ТОЧКА
Point::Point(int x1, int y1)
{
x = x1;
y = y1;
}

int &Point::getx(void)
{
return x;
}

int &point::gety(void)
{
return y;
}

void Point::move(int x1, int y1)
{
hide();
x = x1;
y = y1;
show();
}


// Определение функций - членов класса ПЯТНО
Spot::Spot(int x1, int y1, int r1)
: Point(x1, y1)
{
int size; // размер памяти для хранения изображения
vis = 0;
tag = 0;
r = r1;
pspot = (spot *) new char[size];
}

Spot::~Spot()
{
hide();
tag = 0;
delete pspot;
}

void Spot::show(void)
{
if (!tag)
{
// нарисовать и
// запомнить изображение
tag = 1;
}
else
{
// отобразить запомненное изображение
}
vis = 1;
}

void Spot::hide()
{
if (!vis) return;
// стереть
vis = 0;
}


// Создаются два объекта, показываются,
// затем один перемещается, а другой
// изменяет размеры
int main(void)
{
Spot A(200, 50, 20);
Spot B(500, 200, 30);
A.show();
getch();
B.show();
getch();
A.move(50, 60);
getch();
B.change(3);
getch();
return 0;
}

В этом примере в объекте Spot точка создается как безымянный объект класса Point.

 







Date: 2016-07-25; view: 422; Нарушение авторских прав



mydocx.ru - 2015-2024 year. (0.011 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию