Г. Шилтд - Самоучитель C++ (PDF) (1114887), страница 77
Текст из файла (страница 77)
Для решенияпроблемы потребовался конструктор копий.// Исправленная версия программы#include <iostream>^include <cstdlib>using namespace std;class myclass {int *p ;public:myclass (int i) ;myclass (const myclass s o ) ; // конструктор копий~myclass() (delete p ; }friend int getval (myclass o) ;ПриложениеВ.Ответынавопросыирешенияупражнений _ 535rnyclass: :myclass (int i)ip=new int;cout <:< "Ошибка выделения памяти\п";exit(l) ;}*p=i;}1 1 Конструктор копийmyclass: irnyclass (const myclass & o )fp=new int;// выделение памяти для копииif(!p) {cout « "Ошибка выделения ламяти\п";exit(l) ;}*р=*о.р;}int getval (myclass о)treturn *o.p; // получение значения}int main(){myclass a(l) , b(2) ;cout « getval (a) « " " « getval (b) ;cout « "\n";cout « getval (a) « " " « getval (b) ;return 0;3. Конструктор копий вызывается, когда один объект используется для инициализации другого.
Обычный конструктор вызывается, когда объект создается.5.41. ^include <iostream>#include <cstdlib>536Самоучитель C++using namespace std;long mystrtol(const char *s, char **end, int base = 10)return strtol(s, end, base);int main ()long x;char *sl - "100234";char *p;x = mystrtol{si, &p, 16);cout « "Основание системы счисления 16: " « x « p\n';x - mystrtol(si, &p, 10);cout « "Основание системы счисления 10: " « x « '\г.';x = mystrtol(si, 5p); // основание системы счисления,// заданное по умолчаниюcout « "Основание системы счисления по умолчанию 10: "« х « '\п';return 0;2.
Все параметры, которые получают аргументы по умолчанию, должны находиться правее параметров, которые этих аргументов не получают. Таким образом, после того как вы начали присваивать значения аргументам по умолчанию, все последующие параметры также должны получать свои значенияпо умолчанию. Что касается приведенного в вопросе прототипа функции, тов нем параметр q значения по умолчанию не получает.3. Поскольку функции управления позиционированием курсора у различныхкомпиляторов и сред программирования разные, показано только одно извозможных решений задачи. Следующая программа предназначена для работы в среде программирования Borland C++./* Эта программа работает только в среде программирования Borland C++*/#include <iostream>^include <conio.h>using namespace std;void rnyclreol (int len = -1) ;int main()fint i;Приложение В.
Ответы на вопросы и решения упражнений537gotoxy(1, 1) ;for(i=0; i<24; i++)cout « "abcdefghijklmnopqrstuvwxyzl23456789Q\n";gotoxyd, 2) ;inyclreol () ;gotoxyd, 4) ;myclreol{20) ;return 0;I// Стирание строки на величину, заданную параметром lenvoid inyclreol (int len}{int x, у;x = wherex(); // получение положения по ху = whereyi); // получение положения по уif(len == -1) len = 80 - x;int i = x;for(; i<=len; i++) cout « ' ';gotoxy(x, y); // установка курсораJ4.
Аргумент по умолчанию не может быть другим параметром или локальнойпеременной.5.61. ^include <iostream>using namespace std;int dif(int a, int b){return a — b;}float dif(float a, float b){return a — b;)int main f){int (*pl)(int, int};535Самоучитель C++float (*р2) (float, float);pi = dif; // адрес функции diffint, int)p2 = dif; // адрес функции dif(float, float)cout « pi (10, 5) « ' ';cout « p2!10.5, 8.9} « '\n';return 0;Проверка усвоения материала главы 51. // Перегрузка конструктора date() для параметра типа time_t^include <iostream>^include <cstdio> // заголовок включен для функции sscanffi^include <ctime>using namespace std;class date {int day, month, year;public:date (char *str) ;date (int m, int d, int y) {day = d;month = m;year = y;}// Перегрузка конструктора для параметра типа time_tdate{time_t t) ;void show() {cout « month « '/' « day « '/';cout « year « '\n';date: : date (char *str){sscanf (str, "%d%*c%d%*c%d", fimonth, &day, &year)}date: :date (time_t t){struct tm *p;p = localtirne ( f i t ) ;day = p -> tm_mday;month = p -> trn mon;Приложение^.
Ответы на вопросы и решения упражнений______539year = р -> tm_year;}int main(){// Образование даты с помощью строкиdate sdate("ll/l/92") ;// Образование даты с помощью трех целыхdate idate(ll, I, 92) ;/* Образование даты с помощью параметра типа time_t, что ведет ксозданию объекта, использующего системную датуVdate tdate (time (NULL) ) ;sdate. show() ;idate. show() ;tdate. show() ;return 0;2.
В классе samp определен только один конструктор — конструктор с параметром. Поэтому нельзя объявлять объект типа samp без параметра. (То есть инструкция samp x — это неправильное объявление.)3. Первый довод в пользу перегрузки конструктора состоит в том, что такаяперегрузка обеспечивает гибкость, позволяя вам выбрать в каждом конкретном случае наиболее подходящий конструктор. Другой довод в том, что перегрузка позволяет объявлять как инициализируемые, так и не инициализируемые объекты. Вам может потребоваться перегрузить конструктор для динамического выделения памяти под массив.4.
Ниже представлена основная форма конструктора копий:имя класса (const имя класса ^объект) {тело конструктора5. Конструктор копий вызывается, когда имеет место инициализация, а именно: когда один объект явно используется для инициализации другого, когдаобъект передается в функцию в качестве параметра, когда создается временный объект при возвращении объекта функцией.6.
Ключевое слово overload является устаревшим. В ранних версиях C++ оноинформировало компилятор о том, что функция будет перегружена. В современных компиляторах это ключевое слово не поддерживается.540__Самоучитель C++7. Аргумент по умолчанию — это значение, которое присваивается параметруфункции при ее вызове, если при этом соответствующий аргумент функциине указан.8. ^include <iostream>^include <cstring>using namespace std;void reverse (char *str, int count = 0 ) ;int main ( ){char *sl = "Это проверка";char *s2 = "Мне нравится C++";reverse (si); // Реверс всей строкиreverse (s2, 7); // Реверс первых семи знаковcout « si « '\n';cout « s2 « '\n' ;return 0;void reverse (char *str, int count){int i, j;char temp;i f f l c o u n t ) count = s t r l e n ( s t r ) — 1;f o r ( i = 0 , j=count; i<j .temp = str[ i ];str[ i ] = s t r [ j ] ;str[ j ] - temp;}9.
Все параметры, получающие аргументы по умолчанию, должны находитьсяправее параметров, не получающих таких аргументов.10. Неоднозначность может возникнуть, когда по умолчанию происходит преобразование типа, а также при использовании параметра-ссылки или аргумента по умолчанию.11. Пример неоднозначен, поскольку компилятор не может определить, какуюверсию функции compute() следует вызвать. Вызвать ли первую версию саргументом по умолчанию divisor, или вторую — в которой функция получает только один параметр?Приложение В. Ответы на вопросы и решения упражнений54112. При получении адреса перегруженной функции с помощью указателя, конкретную ее версию определяет способ объявления указателя.
То есть длявсех перегруженных версий функции, адреса которых мы хотели бы получить, должна объявляться своя версия указателя.Проверка усвоения материала в целом1. #include <iostream>using namespace std;void order{int &a, int fib){int t;if (a<b) return;else { // а и b меняются местамиt = a;a = b;b = t;int main(){int x = 10, у = 5;cout « "x: " « x « ", y: " « у « ' \n ' ;order {x, y) ;cout « "x: " « x «: ", y: " « у « ' \n ' ;return 0;2. Синтаксис вызова функции, параметр которой передается по ссылке, идентичен синтаксису вызова функции, параметр которой передается по значению.3. Аргумент по умолчанию, фактически, является компактной записью перегрузки функции, поскольку приводит к тому же результату.
Например, инструкцияint f (int a, int b = 0) ;идентична следующим двум перегруженным функциям:int f (int a) ;int f (int a, int b) ;542Самоучитель С++4. ^include <iostream>using namespace std;class samp {int a;public:samp{) { a = 0; }samp(int n) { a = n; }int get_a() { return a; }};int{main()samp ob ( 8 8 ) ;samp obarray[10];5. Конструкторы копий необходимы, если программист хотел бы точно управлять процессом создания копий объекта.
Это важно только в том случае, если создаваемые по умолчанию поразрядные копии по каким-либо причинамнежелательны.ГЛАВА 6Повторение пройденного1. class myclass {int x, у;public:myclass (int i, int j) ( x = i; у = j; }myclass!) { x = 0; у = 0; }2. class myclass {int x, y;public:myclass (int i = 0, int j = 0) { x = i; у = j; }3. В объявлении функции после появления аргумента по умолчанию не должнобыть обычных аргументов.ПриложениеВ.Ответынавопросыирешенияупражнений_5434. Функции нельзя перегружать, если их отличие только в том, что одна получает параметр по значению, а вторая — по ссылке.
(Компилятор не в состоянии их отличить.)5. Аргументы по умолчанию лучше использовать тогда, когда можно с уверенностью предположить, что при работе приложения одно или более значенийбудут встречаться чаще других. Аргументы по умолчанию лучше не использовать, когда такой уверенности нет.6. Нет, поскольку нельзя инициализировать динамический массив. В этомклассе имеется только один конструктор, которому требуется инициализация.7. Конструктор копий — это особый конструктор, который вызывается приинициализации одного объекта другим.
Такая инициализация имеет место вследующих трех случаях: когда один объект явно используется для инициализации другого, когда объект передается в функцию в качестве параметра, икогда в качестве возвращаемого значения функции создается временныйобъект.Упражнения6.21. // Перегрузка операторов * и / относительно класса coord^include <iostream>using namespace std;class coord {int x, у; // значения координатpublic:coord!) { x = 0; y- 0; }coord (int i, int j) { x = i; у = j; }void get_xy{int &i, int & j ) { i = x; j = y; }coord operator* (coord o b 2 ) ;coord operator/ (coord ob2);// Перегрузка оператора * относительно класса coordcoord coord: : operator* (coord ob2)(coord temp;temp.x = x * ob2.x;temp.