46019 (665326), страница 19

Файл №665326 46019 (Turbo C++ Programer`s guide) 19 страница46019 (665326) страница 192016-07-31СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 19)

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

X::X(int = 5, int = 6)

может принимать двааргумента, один аргумент, либо не принимать аргументов вообще,причем в каждом случаепринимаются соответствующие умолчания. Однако, конструктор по умолчанию Х::Х() не принимаетаргументов вообще, иего не следует путать с конструктором, например, X::X(int = 0), который может либо принимать один аргумент, либо не принимать аргументов.

При вызове конструкторов следует избегать неоднозначностей. В следующем примере возможно неоднозначное восприятие компилятором конструкторапо умолчанию и конструктора, принимающего целочисленный параметр:

class X

(*

public:

X();

X(int i = 0);

*);

main()

(*

X one(10); // так можно: используется X::X(int)

X two; // так нельзя; неоднозначно задано, используется // ли X::X() или X::X(int = 0)

...

return 0;

Конструктор копирования

Конструктор копированиядля класса Х это такой конструктор, который может быть вызван с одним единственным аргументом типа X: X::X(const X&) или X::(const X&, int = 0). В конструкторе копирования допустимыми такжеявляются аргументы по умолчанию. Конструкторыкопирования запускаются при копировании объекта данного класса, обычно в случае объявления с инициализацией объектом другого класса: X x = y. Turbo C++ генерирует конструктор копирования для класса X автоматически, если такой конструктор необходим, но в классе Х неопределен.

Перегрузка конструкторов

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

class X

(*

int integer_part;

double double_part;

public:

X(int i) (* integer_part = i; *)

X(double d) (* double_part = d *)

*);

main()

(*

X one(10); // запускает X::X(int) и устанавливает // integer_part в значение 10

X one(3.14); // запускает X::X(double) ш устанавливает // double_part

...

return 0;

*)

Порядок вызова конструкторов

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

Например, в следующем примере

class Y (*...*)

class X : public Y (*...*)

X one;

вызов конструкторов происходит в следующей последовательности:

Y(); // конструктор базового класса

X(); // конструктор производного класса

В случае множественных базовых классов:

class X : public Y, public Z

X one;

конструкторы вызываются в последовательности их объявления:

Y(); // первыми следуют конструкторы базового класса Z();

X();

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

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

class X : public Y, virtual public Z

X one;

определяет следующую последовательность:

Z(); // инициализация виртуального базового класса Y(); // не-виртуальный базовый класс

X(); // произвольный класс

Либо, в более сложном случае,

class base;

class base2;

class level1 : public base2, virtual public base; class level2 : public base2, virtual public base; class toplevel : public level1, virtual public level1; toplevel view;

Порядок конструирования view будет принят следующий:

base(); // старший в иерархии виртуальный базовый класс // конструируется только однажды

base2(); // не-виртуальная база виртуальной базы level2 // вызывается для конструирования level2

level2(); // виртуальный базовый класс

base2(); // не-виртуальная база для level1

level1(); // другая не-виртуальная база

toplevel();

В случае, когда иерархия класса содержит множественные вхождения виртуального базового класса, данный базовый класс конструируется только один раз. Однако, если существуют и виртуальные,и не-виртуальные вхождения базовогокласса, то конструктор класса запускается одинраз для всехвиртуальных вхождений и один раз для всех не-виртуальных вхождений базового класса.

Конструкторы элементовмассива запускаютсяв порядке возрастания индексов массива.

Инициализация класса

Объект классас компонентами только public и без конструкторов или базовых классов (обычно это структура) может бытьинициализирован при помощи списка инициализаторов.При наличии конструктора класса объекты либо инициализируются, либо имеютконструктор по умолчанию. Последний используется в случае объектов без явной инициализации.

Объекты классов с конструкторами могут быть инициализированы при помощи задаваемых в круглых скобках списков инициализаторов. Этот список используется как список передаваемых конструктору аргументов. Альтернативнымспособом инициализации является использованиезнака равенства, за которымследует отдельное значение. Это отдельное значение можетиметь тип первого аргумента, принимаемого конструктором данного класса; в этом случае дополнительных аргументов либо не существует, либо они имеютзначения по умолчанию. Значение может также являться объектом данного типа класса. В первом случае для создания объекта вызывается соответствующийконструктор. В последнем случае вызывается конструктор копирования, инициализирующий данный объект.

class X

(*

int i;

public:

X(); // тела функций для ясности опущены

X(int x);

X(const X&);

*);

main()

(*

X one; // запуск конструктора по умолчанию

X two(1); // используется конструктор X::X(int)

X three = 1; // вызывает X::X(int)

X four = one; // запускает X::X(const X&) для копирования X five(two); // вызывает X::X(cont X&)

Конструктор может присваивать значения своимкомпонентам следующим образом. Он может принимать значения в качестве параметров и выполнять присваивание компонентам переменным собственно в теле функции конструктора:

class X

(*

int a, b;

public:

X(int i, int j) (* a = i; b = j *)

*);

Либо он может использовать находящийся до тела функции список инициализаторов:

class X

(*

int a, b;

public:

X(int i, int j) : a(i), b(j) (**)

*);

В обоих случаях инициализация X x(1, 2) присваивает значение 1 x::a и значение 2 x::b. Второй способ, а именно список инициализаторов, обеспечивает механизм передачи значений конструкторам базового класса.

Конструкторы базовогокласса должны быть объявлены с атрибутами public или protected, для того, чтобыобеспечить возможность их вызова из производного класса.

class base1

(*

int x;

public:

base1(int i) (* x = i; *)

*);

class base2

(*

int x;

public:

base2(int i) : x(i) (**)

*);

class top : public base1, public base2

(*

int a, b;

public:

top(int i, int j) : base(i*5), base2(j+i), a(i) (* b = j;*)

*);

В случае такойиерархии класса объявление top one(1, 2) приведет к инициализации base1 значением 5, а base2 значением 3. Методы инициализации могут комбинироваться друг с другом.

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

class X

(*

int a, b;

public:

X(int i, j) : a(i), b(a+j) (**)

*);

В пределах класса объявление X x(1,1) приведет к присваиванию числа 1 x::a и числа 2 x::b.

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

class base

(*

int x;

public:

base(int i) : x(i) (**)

*);

class derived : base

(*

int a;

public:

derived(int i) : a(i*10), base(a) (**) // Обратите внимание! // base будет передано неинициализированное a

*)

В данномпримере вызовпроизводного d(1) неприведет к присвоению компоненту базового класса х значения 10. Значение, переданное конструктору базового класса, будет неопределенным.

Если вы хотите иметь список инициализаторов в не-встроенном конструкторе,не помещайте этот список вопределении класса. Вместо этого поместите его в точку определения функции:

derived::derived(int i) : a(i)

(*

...

*)

Деструкторы

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

class X

(*

public:

-X(); // деструктор класса X

*);

Если деструкторне объявлен для класса явно, компилятор генерирует его автоматически.

Запуск деструкторов

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

Когда указатели объектов выходят запределы контекста, неявный вызов деструктора непроисходит. Это значит, чтодля разрушения такого объекта операция delete должна быть задана явно.

Деструкторы вызываются строго в обратной последовательности относительнопоследовательности вызова соответствующих им конструкторов (см. стр.117 оригинала).

atexit, #pragma exit и деструкторы

Все глобальные объекты остаются активными до тех пор, пока не будут выполнены коды во всех процедурах выхода. Локальные переменные, включая те, что объявлены в main, разрушаютсяпри выходе их из контекста. Последовательность выполнения в конце программы Turbo C++ в этом смысле следующая:

- выполняются функции atexit в последовательности их вставки в программу

- выполняются функции #pragma exit в соответствии с кодами их приоритетов

- вызываются деструкторы глобальных переменных.

exit и деструкторы

При вызове exitиз программы деструкторы для каких-либо локальных переменных в текущем контексте не вызываются. Глобальные переменные разрушаются в обычной последовательности.

abort и деструкторы

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

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

class X (*

...

-X();

...

*);

void* operator new(size_t size, void *ptr)

(*

return ptr;

*)

char buffer[sizeof(x)];

main()

(*

X* pointer = new X;

X* exact_pointer;

exect_pointer = new(&buffer) X;// указатель

инициализиру// ется адресом буфера

...

delete pointer;// delete служит для раз-

// рушения указателя

exact_pointer->X::-X();// прямой вызов для отмены

// распределения памяти

*)

Виртуальные деструкторы

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

Внимание: пример проограммы см в файле prog_1.app

Однако, если ни один из деструкторов не был объявлен виртуальным,delete palette[0], delete palette[1] и delete palette[2] вызывают только деструктор дляклассаcolor.Это приведет к неправильному разрушению первых двух элементов, которые фактически имели тип red и brightred.

Характеристики

Тип файла
Документ
Размер
2,71 Mb
Тип материала
Учебное заведение
Неизвестно

Список файлов реферата

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6513
Авторов
на СтудИзбе
302
Средний доход
с одного платного файла
Обучение Подробнее