Г. Шилтд - Самоучитель C++ (PDF) (1114887), страница 74
Текст из файла (страница 74)
Она не должна быть рекурсивной. Вней не может быть инструкций goto и switch. И наконец, она не должна содержать статических переменных.6. sample ob(100, ' X ' ) ;Упражнения3.11. Инструкция присваивания х = у неправильна, поскольку ell и с!2 — это дваразных класса, а объекты разных типов присваивать нельзя.2. #include <iostream>using namespace std;#<3efine SIZE 100502_Самоучительclass q_type {. int queue [SIZE]; // содержит очередьint head, tail; // индексы вершины и хвостаpublic:q_type(); // конструкторvoid q(int num) ; // запоминаниеint deq(); // удаление из начала очереди};// Конструкторq_type: :q_type{){head - tail = 0;}// Помещение значения в очередьvoid q_type : : q ( int num)if (tail -I- l==head || (tail + 1«SIZE SS Ihead)} {cout « "Очередь полна";return;}tail-м-;if (tail==SIZE) tail = 0; // круговой циклqueue [tail] = num;// Выталкивание значения из очередиint q_type: :deq()if (head==tail) {cout « "Очередь пуста";return 0;head++;if (head==SIZE) head = 0; // круговой циклreturn queue[head];int main{)q_type ql, q2;int i;for(i=l; i<=10; i++) {ql.q(i);}// присваивание одного объекта очередь — другомуq2 = ql;C++Приложение В.
Ответы на вопросы и решения упражнений// демонстрация того факта,// что обе очереди имеют одинаковое содержимоеfor(i=l; i<=10; i-н-)cout « "Элемент очереди 1: " « ql . deq ( ) « "\n";for(i=l; i<=10; i++)cout « "Элемент очереди 2: " « q2.deq() « "\n";return 0;3. Если для хранения очереди память выделяется динамически, тогда, послеприсваивания одной очереди другой, когда объекты удаляются, для очереди,стоящей в инструкции присваивания слева, память освобождена не будет, адля очереди, стоящей в инструкции присваивания справа, память будет освобождена дважды. Оба этих условия неприемлемы, что и вызывает ошибку.3.21.
^include <iostream>using namespace std;ttdefine SIZE 10// Объявление класса stack для символовclass stack {char stck[SIZE]; // содержит стекint tos; // индекс вершины стекаpublic:stack (}; // конструкторvoid push (char ch) ; // помещает символ в стекchar pop (); // выталкивает символ из стека};// Инициализация стекаstack: :stack (){cout « "Работа конструктора стека \п" ;tos = 0;/ / Помещение символа в стекvoid stack: :push (char ch){if (tos==SIZE) {cout « "Стек полон \п";return;504Самоучитель C++s t c k f t o s ] = ch;tos-n-;'// Выталкивание символа из стекаchar stack::pop()if (tos=0) {cout « "Стек пуст \п";return 0; // возврат нуля при пустом стекеtos—;return stck[tos];void showstack{stack o) ;int main()\stack si;int i;si.push('a'};sl.push('b');sl.push('c');showstack(sl);// объект si в функции main{) по-прежнему существуетcout « "Стек si все еще содержит следующее: \п";for(i=0; i<3; i-н-) cout « sl.popO « "\n";return 0;// Вывод содержимого стекаvoid showstack(stack o)char c;// когда выполнение этой инструкции завершится,// стек о опустеетwhile(с=о.рор()} cout « с « "\п";cout « "\п";Эта программа выводит на экран следующее:Работа конструктора стекасbаПриложение В.
Ответы на вопросы и решения упражнений505Стек пустСтек si все еще содержит следующее:сьа2, Память для хранения целого, на которую указывает указатель р в объекте о,который используется при вызове функции neg(), освобождается, когда призавершении функцией neg() своей работы копия объекта о удаляется; однакоэта память все еще необходима для объекта о в функции mainO3.31. ^include <iostreaici>using namespace std;class who {char name;public:who(char c) {name = c;cout « "Создание объекта who tt";cout « name « "\n";~who() { cout « "Удаление объекта who #" « name « "\n"; }who rnakewho ()fwho temp('В') ;return temp;int main()who ob('A');makewho();return 0;2. Имеется несколько ситуаций, в которых возвращать объект было бы неправильно.
Вот одна из таких ситуаций: если при создании объекта файл открывается, а при удалении объекта файл закрывается, тогда к закрытию файлаприведет удаление временного объекта, которое происходит, когда функциявозвращает объект.Самоучитель C++5063.41. ^include <iostream>using namespace std;class pr2; // предварительное объявлениеclass prl {int printing;.public:prl() { printing = 0; }void set_print(int status) { printing = status; }friend int inuse{prl ol, pr2 o2);class pr2 {int printing;//...public:pr2() { printing = 0 ; }void set__print (int status) { printing = status; }//...friend int inuse{prl ol, pr2 o2);// Возвращает истину при занятом принтереint inuse(prl ol, pr2 o2){if(ol.printing I I o2,printing) return 1;else return 0;int main(}prl pi;pr2P2;if(linuse(pi, p2)) cout « "Принтер свободен\п";cout « "Установка для печати принтера pi ..An";pl.set_print (1);if(inuse(pl, p2)) cout « "Теперь принтер занят\п"cout « "Отключение принтера р! ...
\п";pl.setjprint(0);if (linuse{pi, p2)) cout « "Принтер свободен\п";Приложение В. Ответы на вопросы_и_решения_ упражнений507cout « "Подключение принтера р2 . . . \п";p2.set_print(l);if{inuse{pl, p2)) cout « "Теперь принтер занят\п";return 0;Проверка усвоения материала главы 31. Для того чтобы присвоить один объект другому, необходимо, чтобы тип обоих объектов был одинаков.2.
Присваивать obi и оЬ2 неправильно, так как память, на которую в началеуказывал указатель р объекта оЬ2, теряется, поскольку это значение указателяр при присваивании переписывается. Таким образом, такую память становится невозможно освободить, и наоборот, память, на которую в начале указывал указатель р объекта obi, при удалении этого объекта освобождаетсядважды, что может привести к повреждению системы динамического выделения памяти.3.
int light (planet p){return p.getjnilesU / 186000;4. Да.5. // Загрузка алфавита в стек^include <iostream>using namespace std;kiefine SIZE 27// Объявление класса stack для символовclass stack {char stck[SIZE]; // содержит стекint tos; // индекс вершины стекаpublic:stack (); // конструктор•void push (char ch) ; // помещает символ в стекchar рор(); // выталкивает символ из стека\.// Инициализация стекаstack: : stack (){cout « "Работа конструктора стека \п";Самоучитель C++508tos - 0;/I Запись символа в стекvoid stack: :push(char ch)(if (tos==SISE) {cout « "Стек полон \п";return;1stckftos] = ch;tos++;// Выталкивание символа из стекаchar stack: :pop(){if (tos==0) {cout « "Стек пуст \п";return 0; // возврат нуля при пустом стеке1tos — ;return stck[tos];void showstack (stack o) ;stack loadstackO;int main()tstack si;si = loadstackO ;showstack (si) ;return 0;// Вывод на экран содержимого стекаvoid showstack(stack о){char с;// когда выполнение этой инструкции завершится, стек о опустеетwhile(c=o.pop(}) cout « с « "\п";cout « "\п";// Загрузка стека символами алфавитаstack loadstackf)Приложение В.
Ответы на вопросы и решения упражнений509stack t;char с;for ( с= ' а ' ; с<= ' z ' ; с++ ) t . push ( с ) ;return t;6. При передаче объекта функции в качестве аргумента и при возвращенииобъекта из функции в качестве возвращаемого значения, создается временный объект, который удаляется при завершении работы функции. При удалении временного объекта деструктор может удалить в программе нечто такое, что может еще пригодиться.7.
Дружественная функция — это функция, не являющаяся членом класса, нообеспечивающая доступ к закрытой части класса, для которого она дружественна. Еще раз, дружественная функция имеет доступ к закрытой частикласса, для которого она дружественна, но не является членом этого класса.Проверка усвоения материала в целом1. // Загрузка алфавита в стек^include <iastream>^include <cctype>using namespace std;^define SIZE 27// Объявление класса stack для символовclass stack {char s t c k f S I Z E ] ; // содержит стекint tos; // индекс вершины стекаpublic:s t a c k ( ) ; // конструкторvoid push(char ch) ; // помещает символ в стекchar pop(); // выталкивает символ из стека// Инициализация стекаstack: : stack {}{cout « "Работа конструктора стека \пtos = 0;// Запись символа в стекvoid stack: : push (char ch)510Самоучительif (tos— SIZE) {cout « "Стек полон \п";return;}stck[tos] = ch;tos++;}// Выталкивание символа из стекаchar stack: :pop(){if (tos—0) {cout « "Стек пуст \п";return 0; // возврат нуля при пустом стекеtee— ireturn stckftos];void showstack (stack o) ;stack loads t ack ();stack loadstack(int upper);int rnainO{stack si, s2, s3;si = loadstackO ;showstack (si) ;,,// используется верхний регистрs2 = loadstack(l) ;showstack (s2) ;// используется нижний регистрs3 = loadstack(O) ;showstack (s3} ;return 0;// Вывод на экран содержимого стекаvoid showstack (stack о){char с;// когда выполнение этой инструкции завершится, стек о опустеетwhile (c=o.
pop (}) cout « с « "\п";ПриложениеВ.Ответынавопросыирешенияупражнений_511cout « "\п";// Загрузка стека символами алфавитаstack loadstack(){stack t;char с;for(c='a'; c<='z'; с++) t.push(c)return t;/* Загрузка стека символами алфавита . Символами верхнего регистра,если переменная upper равна 1, в противном случае символами нижнегорегистра */stack loadstack{int upper)(stack t;char c;if (upper) с = 'A' ;else с = 'a' ;for (; toupper (c}<='Z' ; с++) t .push (c) ;return t;2. ^include <iostream>^include <cstring>^include <cstdlib>using namespace std;class strtype (char *p;int len;public:strtype (char *ptr) ;-strtype ();void show ( ) ;friend char *get_string( strtype *ob) ;};strtype: : strtype (char *ptr)(len=strlen(ptr) ;p=(char *) malloc(len+l) ;512__________СамоучительC++cout « "Ошибка выделения памяти\п";exit(l) ;}strcpyfp, ptr);strtype : : -strtype ( ){cout « "Освобождение памяти по адресу р\п";free (p) ;}void strtype: : show (){cout « p « " - длина: " « len;cout « "\n";}char *get_string (strtype *ob)freturn ob->p;}int main!){strtype si ("Это проверка-');char *s;si .
show ( ) ;// получение указателя на строкуs = get_string(£sl) ;cout « "Это строка, содержащаяся в объекте si: ";cout « s « "\n";return 0 ;3. Итог эксперимента следующий: Да, если один объект производного классаприсваивается другому, то данные базового класса также копируются. Далееприводится программа для демонстрации этого факта.#include <iostream>using namespace std;class base {int a;public:Приложение В. Ответы на вопросы и решения упражнений513void load_a(int n) { а = n; }int get_a() { return a; }};class derived: public base {int b;public:void load_b (int n) { b = n; }int get_b() { return b; }int main()derived obi, ob2;obl.load_a(5);obl.load_b(10};// Объект obi присваивается объекту оЬ2ob2 = obi;cout « "Это переменные а и b объекта obi: ";cout « obl.get_a() « ' ' « obl.get_b() « "\n";cout « "Это переменные а и b объекта оЬ2: ";cout « ob2.get_a() « ' ' « ob2.get_b() « "\n";/* Как вы, вероятно, догадались, выводимые на экран значенияодинаковы для обоих объектов*/return 0;ГЛАВА 4Повторение пройденного1.
При присваивании одного объекта другому объекту того же типа, текущиезначения данных всех членов объекта, стоящего справа от оператора присваивания, передаются соответствующим членам объекта, стоящего слева отоператора присваивания.2. При присваивании одного объекта другому, ошибка может случиться тогда,когда эта операция перезаписывает важные данные, уже существующие в целевом объекте.