Г. Шилтд - Самоучитель C++ (PDF) (1114887), страница 75
Текст из файла (страница 75)
Например, если значение указателя на динамически выделенную область памяти или на открытый файл будет перезаписано, то очевидно,что тогда теряется исходное значение указателя.Самоучитель С++_5743. Если объект передается функции в качестве аргумента, создается его копия.Однако конструктор копии не вызывается. При завершении работы функции, когда объект удаляется, вызывается деструктор копии.4. Нарушение принципа независимости объекта и его копии при передаче параметра может возникать в нескольких ситуациях.
Например, если деструктор освобождает динамическую память, тогда эта память для аргумента будетпотеряна. В общем случае, если деструктор удаляет что-то, что требуется исходному аргументу, аргумент будет испорчен.5. #include <iostream>using namespace std;class summation {int num;long sum; // суммирование чисел numpublic:void set_sum(int n) ;void show_sum{) {cout « " сумма чисел " « num « " равна " « sum « "\n";void summation: :set_sum(int n){int i;num = n;sura = 0;for(i=l; i<=n;sum += i;summation make_sum(){int i;summation temp;cout « "Введите число:cin » i;temp. set_sum(i) ;return temp;int main ( }{summation s;ПриложениеВ.Ответынавопросыирешенияупражнений_515s = make_sum() ;s .show_sura{) ;return 0;6. Для некоторых компиляторов требуется, чтобы во встраиваемых функциях небыло циклов.7.
tinclude <iostream>using namespace std;class myclass {int num;public:myclass (int x) { num = x; }friend int isneg (myclass ob) ;int isneg (myclass ob){return (ob.num < 0) ? 1: 0;}int main( ){myclass a(-l), b(2);cout « isneg(a) « ' ' « isneg(b);cout « "\n";return 0;8. Да, дружественная функция может быть дружественной более чем одномуклассу.Упражнения4.11. #include <iostream>using namespace std;class letters (char ch;516___Самоучительpublic:letters (char с) { ch = с; }char get_ch() ( return ch; }int main { ){letters ob [10] = { 'a', 'b', 'c1, 'd', '&',•f, 'g1, 'h', 'i', 'j' };int i;for(i=0; i<10; i++)cout « ob[ i ].get_ch() « ' ';cout « "\n";return 0;2.
^include <iostrearti>using namespace std;class squares {int num, sqr;public :squares {int a, int b) { num = a; sqr = b; }void show() {cout « num « ' ' « sqr « "\n"; }!iint main (){squares ob[10] = {squares (1, 1) ,squares (2, 4) ,squares (3, 9) ,squares (4, 16) ,squares (5, 25) ,squares (6, 36} ,squares (7, 49) ,squares (8, 64) ,squares (9, 81) ,squares (10, 100} ,};int i;for{i=0; i<10; i++) ob [ i ] . show ( ) ;return 0;C++ПриложениеВ.Ответынавопросыирешения3. ttinclude <iostream>using namespace std;class letters {char ch;public:letters (char c) { ch = c; }char get_ch() ( return ch; )int main{){letters ob[10] = {letters ( 'a' ) ,1letters {'b ) ,letters ('c') ,letters ('d') ,1letters ( 'e ) ,letters Cf) ,letters ('g') ,rletters{'h ) ,1letters ( ' i ) ,letters (' j M};int i;for(i=0; i<10; i++)cout « ob [ i ] .
get_ch ( } «cout « "\n";return 0 ;4.21. // Вывод содержимого массива в обратном порядке^include <iostream>using namespace std;class samp {int a, b;public:sarap{int n, int m) { a = n; b = m; }int get_a{) { return a; }int get_b{) { return b; }упражнений_517Самоучитель C++518int main{)samp ob[4] = (samp (1, 2),samp (3, 4),samp(5, 6),samp(1, 8)int i;sarnp *p;p = &ob[3]; // получение адреса последнего элемента массиваfor(i=0; i<4cout « p -> get_a() « ' ';cout « p -> get_b!) « "\n";p — ; // переход к предыдущему объектуcout « "\n";return 0 ;2. /* Создание двумерного массива объектов с доступом к элементам черезуказатель*/#include <iostream>using namespace std;class samp {int a;public:samp (int n) { a = n; }int get_a ( ) { return a; }int main { )1samp ob [4] [2] = {1, 2,3, 4,5, 6,int i;ПриложениеВ.Ответынавопросыирешенияупражненийsamp *p;р = (samp *) ob;for(i=0; i<4; icout « p->get_a ( } « ' ' ;P++;cout « p->get_a() « "\n";P++;}cout « "\n";return 0;4.31.
// Использование указателя this#include <iostream>using namespace std;class niyclass {int a, b;public:myclass(int n, int m) { this->a = n; this->b = m; }int add() { return this->a + this->b; }void showf) ;};void myclass::show()(int t;t = this->add(); // вызов функции-членаcout « t <<"\n";}int main(){myclass ob(10, 14);ob.show();return 0;_519520Самоучитель C++4.41. ttinclude <iostream>using namespace std;int main{){float *f;long *1;char *c;f = new float;1 = new long;с = new char;if (!f I I !1 I I !c) {cout « "Ошибка вьщеления памяти.return 1;}*f = 10.102;*1 = 100000;*c = 'A';cout « *f « ' ' « *1 « ' ' « *c;cout « '\n';delete f; delete 1; delete c;return 0;2.
^include <iostream>^include <cstring>using namespace std;class phone {char name[40];char number[14];public:void store(char *n, char *mm) ;void show{) ;void phone::store(char *n, char *num)strcpy(name, n);strcpy (number, mm) ;ПриложениеВ.Ответынавопросыирешенияупражнений_521void phone: : show ( ){cout « name « ": " « number,cout « "\n";)intrnain{)iphone *p;p = new phone;if(!p) (cout « "Ошибка выделения памяти.";return 1;}p->store( "Исаак Ньютон", "111 555-2323");p->show ( ) ;delete p;return 0;3.
В случае неудачной попытки выделения памяти, оператор new может либовозвратить нулевой указатель, либо возбудить исключительную ситуацию.Чтобы выяснить, какой механизм используется в вашем компиляторе, необходимо просмотреть соответствующую техническую документацию. В соответствии с требованиями стандарта по C++, оператор new по умолчаниювозбуждает исключительную ситуацию.4.51.
char *p;p = new char[100] ;// ....strcpy(p, "Это проверка"};2. ^include <iostream>using namespace std;int main()<double *p;.p = new double(-123.0987);522Самоучитель C++cout « *р « '\n';return 0;4.61. ^include <iostream>using namespace std;void rneg(int &i); // версия функции со ссылкойvoid pnegfint *i); // версия функции с указателемint main (}{int i = 10;int j = 20;rneg(i);pneg(sj);cout « i « ' ' « j « '\n';return 0;// использование параметра-ссыпкиvoid rneg(int si)// использование параметра-указателяvoid pneg(int *i)*i = -*i;2. При вызове функции tripleQ адрес d получен явно, посредством оператора &.Это ненужно и неправильно. При использовании ссылки в качестве параметра перед аргументом не ставится оператор &.3.
Адрес параметра- ссылки передается в функцию автоматически. Для получения адреса нет необходимости производить какие бы то ни было действия.Передача по ссылке быстрее, чем передача по значению. При передаче поссылке не делается копии аргумента и поэтому не бывает сторонних эффектов, связанных с вызовом деструктора копии.Приложение В. Ответы на вопросы и решения упражнений5234.71. В исходной программе объект передается в функцию show() по значению.
Поэтому делается его копия. Когда функция showQ возвращает свое значение,копия удаляется и при этом вызывается деструктор копии. Это приводит к освобождению памяти, на которую указывает указатель р, но освобожденная память все еще необходима аргументам функции show(). Здесь представлена правильная версия программы, в которой, для того чтобы предотвратить появление копии при вызове функции, в качестве параметра используется ссылка:// Теперь программа исправлена^include <iostream>^include <cstring>#include <cstdlib>using namespace atd;class strtype {char *p;public:strtype(char *s) ;~strtype() { delete [] p; }char *get() ( return p; }};strtype::strtype(char *s)int 1;1 = strlen(s) + 1;p = new char [1] ;cout « "Ошибка выделения памяти\п";exit(l);strcpy{p, s) ;1// Проблема решена с помощью параметра -ссылкиvoid show(strtype sx){char *s;s = x.get () ;cout « s « "\n";int main(){strtype а ("Привет") , b ("Здесь") ;524Самоучитель C++show(a);show(b) ;return 0;4.81.
// Пример защищенного двумерного массива^include <iostream>ttinclude <cstdlib>using namespace std;class array (int isize, jsize;int *p;public :array (int i, int j);int&put(int i, int j);int get (int i, int j);};array: : array (int i, int j){p = new int [ i * j ] ;if(!p) (cout « "Ошибка выделения ламятиЛп";exit(l) ;isize = i;jsize = j;i// Запись значения в массивint fiarray: :put (int i, int j)| i>=isize I I j<0 I I j>=jsize) {cout « "Ошибка, нарушены границы массива! !! \n";exit С 1 ) ii}return p[i * jsize + j]; // возврат ссылки на p[ i ]// Получение значения из массиваint array: :get (int i, int j)(if(i<0 || i>=isize I I j<0 I I j>=jsize} {cout « "Ошибка, нарушены границы массива! ! !\n";exit ( 1 ) ;Приложение В.