Г. Шилтд - Самоучитель C++ (DJVU) (1114955), страница 24
Текст из файла (страница 24)
т)1ттс1пбе <1оз~геап* пя1по патвеярасе зсдт с1аяя ктус1азз ( роЫ1с т щус1аяя(): птус1аяз (сопя1щус1аяя ьо); тус1аяя й (,т; Обычнъвт конструктор щус1аяя::шус1азз() ( соШ « "Работа обычного конструктора'тп"1 // Конструктор копий ктусьазя: ттвус1азз (сопзсщус1аяя Яо) ( сопя « "Работа конструктора копийт,п" 1 Возвращение объекта щус1аяя твус1азят щус1аяя бещрт гегпгп гетттр; 1пс ткауп() тус1аяя оЬ оЬ1=оЬЗ.Г() гесигп О; 2. Объясните, что в следующей программе неправильно, и исправьте ее. в этой программе имеется ощибка 61пс1ит)е <1озггеатв> Функций Глава Перегрузка 157 ((гпс1пс)е <свГг(11Ь> иыпя пагпеврасе вес(; пус1евз: ппус1авв [1пс 1) р.=пеы 1пгг 1Г(!р) сонг « "Овибка выделения памя'гйп"г ехьс (1); р=г ( (пГ дес~га1(шус1авв о) ге(пгп *о.р; // получение значения 1пг тагп () гнус(авв а(1), Ь(2); соус «сеСча1 (а) « '* " «дег~ а1 (Ы; соцс « "~п"г сосс « дейча1(а) « " " « се(.ча1(о); гегагп О; 3.
Объясните своими словами, зачем нужен конструктор копий и чем он отличается от обычного конструктора. 5.3. Устаревшее ключевое слово очег1оаб с(авв гаус)авв ( 1пк *р; рпЫ ко: тус1аав (1пг. (); -тус1авз () (г(е)е(е р; ) ггтепс) 1п( оеега1 (п~ус1авв с); В ранних версиях С++ для создания ключевое слово очег1оай. Хотя ключевое ляторах больше не поддерживается, вы ствующих профаммах, поэтому полезно перегружаемых функций требовалось слово оуег(оад в современных компи- все еще можете встретить его в суще- знать, как оно использовалось. т53 Самоучитель С~-~ Ниже показана основная форма ключевого слова оуег1оав: о~.
ет1оай имя $унации," Здесь имя функции — это имя перегружаемой функции. Перед этой инструкцией должно находиться объявление перегружаемой функции. Например, следующая инструкция сообщает компилятору, что вы будете перегружать функцию 1пцегО: оъ.ею1оао ' Ьпет ((; Ключевое слово обжег!оаб является устаревшим и в современных компиляторах С++ не поддерживается. 5.4. Аргументы по умолчанию В синтаксисе С++ имеется элемент, который имеет непосредственное отношение к перегрузке функций и называется аргументом по умолчанию (йе~пиИащитепг). Аргумент по умолчанию позволяет вам, если при вызове функции соответствующий аргумент не задан, присвоить параметру значение по умолчанию. Как вы увидите далее, применение аргумента по умолчанию является скрытой формой перегрузки функций. Чтобы передать параметру аргумент по умолчанию, нужно в инструкции определения функции приравнять параметр тому значению, которое вы хотите передать, когда при вызове функции соответствующий аргумент не будет указан.
Например, в представленной ниже функции двум параметрам по умолчанию присваивается значение О: чоЫ т(глЕ. а = О, 1пт Ъ = О); Обратите внимание, что данный синтаксис напоминает инициализацию переменных. Теперь эту функцию можно вызвать тремя различными способами. Во-первых, она может вызываться с двумя заданными аргументами. Вовторых, она может вызываться только с первым заданным аргументом.
В этом случае параметр Ь по умолчанию станет равным нулю. Наконец, функция ГЦ может вызываться вообще без аргументов, при этом параметры а и Ь по умолчанию станут равными нулю. Таким образом, все следующие вызовы функции ГЦ правильны: а и Ь ыо умолчанию равны О Г(10(.- тт а равно 10, Ь но умолчанию равно О Г(10, 99(; т/ а равно 10, Ь равно 99 Глава 5. Перегрузка функций Из этого примера должно быть ясно, что невозможно передать по умолчанию значение а и при этом задать Ь. Когда вы создаете функцию, имеющую один или более передаваемых по умолчанию аргументов, эти аргументы должны задаваться только один раз: либо в прототипе функции, либо в ее определении, если определение предшествует первому использованию функции. Аргументы по умолчанию нельзя задавать одновременно в определении и в прототипе функции.
Это правило остается в силе, даже если вы просто дублируете одни и те же аргументы по умолчанию. Как вы, вероятно, догадываетесь, все параметры, задаваемые по умолчанию, должны указываться правее параметров, передаваемых обычным путем. Больше того, после того как вы начали определять параметры по умолчанию, параметры, которые по умолчанию не передаются, уже определять нельзя. Еще несколько слов об аргументах по умолчанию: они должны быть константами или глобальными переменными.
Они не могут быть локальными переменными или другими параметрами. 1. Программадля иллюстрации вышеописанной функции: // Первый простой пример аргументов по умолчанию $1пс1пбе сьовСкевтп> пв)пя пагпеврасе вес(1 чоЫ Г((п1 а = О, (пт Ь = О) сои(« "а: "<са«",Ь: "«Ь; сове сс 'Хп'; 1п1 тпа1п О '.()1 Г(10)) й(10, 99); ге(игп 0; Как и следовало ожидать, на экран выводится следующее: гс О, Ь: О а: 1О, Ь: О а: 10, Ь: 99 160 Самоучитель с++ Запомните, если первый аргумент задан по умолчанию, все последующие параметры должны также задаваться по умолчанию. Например. такое небольшое изменение функции (Ц приведет к ошибке при компиляции программы: чоЫ г(1пс а = О, гпс Ь) l/ Неправильно! Параметр Ь тоже должен задаваться по умолчанию соцс « "а: " « а « ", Ь: " « Ью соцс « ' 1п'; 2.
Чтобы понять, какое отношение аргументы по умолчанию имеют к перегрузке функций, рассмотрим следующую программу, в которой перегружается функция гее$ агеа(). Эта функция возвращает площадь прямоугольника. /* Расчет площади прямоугольника с использованием перегрузки функций * / Фьпс1цс(е <1ояггеага> ця 1по папе ярасе асс(; Возвращает площадь неравностороннего прямоугольника г)оцЬ1е геев агеа (боцЬ1е 1епдГЬ, с(оцЬ1е мьЖЬ) ( геецгп 1епусй * иЫсп; // Возвращает плошадь квадрата г(оиЫе гесг агеа (г(оиЬ1е 1епдг)т) ( гетигп !епдгЬ * )епнтЬ; ) (п( гваьп () ( сопя « "площадь прямоугольника 10 х В.В равна: соде « гасе агеа(10,0, 5.8) « ' хп'р соцг « "площадь квадрата 10 х 10 равна: " ( соц' « гесс агеа(10.0) « '~п'; гегигп 0; В этой программе функция гее1 агеаО перегружается двумя способами.
В первом — функции передаются оба размера фигуры. Эта версия используется для прямоугольника. Однако в случае квадрата необходимо задавать только один аргумент, поэтому вызывается вторая версия функции гес1 агеа(). Глава Г1ерегрузка Функций 161 Если исследовать этот пример, то становится ясно, что на самом деле в такой ситуации нет необходимости в двух функциях. Вместо этого второму параметру можно по умолчанию передать некоторое значение, действующее как флаг для функции ген агеаО.
Когда функция встретит это значение, она дважды использует параметр 1епфй. Пример такого подхода: /* Расчет площади прямоугольника с передачей аргументов по умолчанию * Мтпс1пае <'оя хеащ> ия1пу пащеярасе ясгз; Возвращает площадь прямоугольника аоиЬ1е гесс агеа (с1оиЬ1е 1епоги, г1опЬ1е и1с1ГЬ = О) 1Г (! ххах~ 1 иьстГЬ =- 1епцхи; гегпгг. 1епохЬ * и1огЬ; ш1 пеатп1) ( сои1 « "площадь прямоугольника 1О х 5.8 равна: соШ « гесГ агеа110.0, 5.91 « '~п'; сонг « "плошадь квадрата 10 х 10 равна: сопт « гесс агеа110.
01 « '~п'; гегнгп 0; Теперь параметру туи)й по умолчанию присваивается нуль. Такое значение выбрано потому, что не бывает прямоугольника с нулевой стороной. (Фактически, прямоугольник с нулевой стороной — это линия.) Таким образом, когда в геа1 агеаО встречается такое, переданное по умолчанию значение, для ширины прямоугольника автоматически используется параметр !ела.
Как показано в этом примере„аргументы по умолчанию часто обеспечивают простую альтернативу перегрузке функций. (Конечно, имеется масса ситуаций, в которых перегрузка функций необходима по-прежнему.) 3. Передавать конструкторам аргументы по умолчанию не только правильно, но и вполне обычно. Как отмечалось ранее в этой главе, часто конструктор перегружается просто для того, чтобы могли создаваться как инициализируемые, так и неинициализируемые объекты. Во многих случаях можно избежать перегрузки конструктора путем передачи ему одного или более аргументов по умолчанию.
Например, рассмотрим следующую программу: вьпс1пое <ьояггеап> ия1пд патпеярасе яхс1; 162 Самоучитель С++ с1аяя п~ус1аяя ( тп х; рпЫ1с: /" Использование аргумента по умолчанию вместо перегрузки конструктора * тус1аяв(1л и = О) ( х = п; 1пг деех() ( гегвгп х; 1пс ва1п () ( пус1аяя о1(10); 11 обьявление с начальным значением п~ус1аяя о2; !! объявление без начального значения соШ « "о1: " « о1,десх() « '',и'; сопС « "о2: " «о2,дегх() « *1п'; тегш.п О; Как показано в этом примере, путем передачи по умолчанию параметру п нулевого значения, можно создавать не только объекты, имеющие явно заданные начальные значения, но и такие. для которых достаточно значений, задаваемых по умолчанию.
4. Другим хорошим применением аргумента по умолчанию является случай, когда с помошью такого параметра происходит выбор нужного варианта развития событий. Можно передать параметру значение по умолчанию так, чтобы использовать его в качестве флага, сообшаюшего функции о необходимости продолжить работу в обычном режиме. Например, в следующей программе функция рпп10 выводит строку на экран. Если параметр Лов равен значению!йвоге, текст выводится в том виде, в каком он задан. Если параметр )юв равен значению вррег, текст выводится в верхнем регистре. Если параметр Мои равен значению!оиег, текст выводится в нижнем регистре.