08.06.2008, 01:02
общий
это ответ
Здравствуйте, Белоус Владимир Владимирович!
К задаче 1.
Ошибка в вашей программе хорошо известна. Её допускают, если функция возвращает объект, а в деструкторе освобождается память, выделенная при создании этого объекта. Решить проблему можно, правильно определив конструктор копий.
Чтобы понять почему это так, рассмотрим, что происходит, когда функция (или оператор) возвращает объект. Возьмём, к примеру ваш оператор сложения.
mass operator+(mass ob)
Чтобы вернуть объект mass, нужно объявить где-то в теле функции переменную соответствующего типа. У вас это
mass temp(ob.s);
При таком объявлении создаётся локальный объект, и в конструкторе выделяется память:
a = new int[s];
Этот объект уничтожается при выходе из функции, при этом будет вызван его деструктор, и память будет освобождена. Соответствующая строчка в деструкторе:
delete [] a;
Функция должна вернуть этот объект, поэтому до его уничтожения делается копия. Эта копия используется для вычисления выражения, в которое входит возвращённое функцией значение, а затем тоже уничтожается. При этом снова вызывается деструктор.
В вашей программе конструктор копий не определён, поэтому при создании копии
используется конструктор копий по умолчанию, который просто копирует указатель на начала массива a. Переменная temp.a, и соответствующая переменная в копии этого массива указывают на одну и ту же область памяти, которая освобождается (!) при выходе из функции. Далее делается попытка использования этой памяти, а потом повторного её уничтожения, что вызывает ошибки исполнения.
Естественно, что в таких случаях в конструкторе копий должна выделяться память:
mass (const mass& m){
s = m.s;
a = new int [s];
for (int i=0; i<s; i++) a[i]=m.a[i];
}
Добавление такого конструктора решает проблему.
Ваша программа, в которую добавлен конструктор копий и внесены другие небольшие поправки, приведена в приложении. (Программа не будет работать, если закомментировать конструктор копий.)
Примечание.
Проблемы, связанные с разной длиной массивов, конечно тоже возможны (и их наверное нужно решать), но у вас они не проявляются, так как все массивы имеют одну длину, которая определяется переменной size в функции main().
Приложение:
/*Создайте класс защищенного массива, в котором реализована проверка выходаза границы массива. Перегрузите операторы: [ ], =, +, -, <<, >>*/#include <iostream>#include <cstdlib>#include <conio.h>using namespace std;const int N = 100;class mass{ int *a; int s; public:mass (int size = N){ s = size; a = new int [s]; for (int i=0; i<size; i++) a[i]=0;}mass (const mass& m){ s = m.s; a = new int [s]; for (int i=0; i<s; i++) a[i]=m.a[i];}int &operator[] (int i);mass operator+ (mass ob);mass operator- (mass ob);mass operator= (mass ob);~mass(){ delete [] a;}friend istream & operator>> (istream&, mass&);friend ostream & operator<< (ostream&, const mass &);};int& mass::operator[](int i){ if (i<0 || i>= s){ cout<<"Limits are exceeded\n"; exit(1); } return a[i];}mass mass::operator+(mass ob){ mass temp(ob.s); for (int i = 0; i<ob.s; i++){ temp.a[i] = ob.a[i] + a[i]; } return temp;}mass mass::operator-(mass ob){ mass temp(ob.s); for (int i = 0; i<ob.s; i++){ temp.a[i] = a[i] - ob.a[i]; } return temp;}mass mass::operator=(mass ob){ mass temp(ob.s); for (int i = 0; i<ob.s; i++){ a[i] = ob.a[i]; } return *this;}istream &operator>> (istream &input, mass& put){ for (int i=0; i<put.s; i++){ input >> put.a[i]; } return input;}ostream &operator<< (ostream& output, const mass &put){ for (int i = 0; i<put.s; i++){ output << put.a[i] << " "; if ((i+1)%10==0) output << endl; } if (i%10==0) output << endl; return output;}void main(){ int size; cout << "Enter dimention of the arrays: ", cin >> size; mass ob1(size), ob2(size), ob3(size); cout << "Enter elements of the 1st object: " << endl; for (int i = 0; i<size; i++) cin >> ob1[i]; cout << endl; cout << "First object: "; for (i = 0; i<size; i++) cout << ob1[i] <<" "; cout << endl; cout << "Enter elements of the 2nd object: " << endl; for (i = 0; i<size; i++) cin >> ob2[i]; cout << endl; cout << "Second object: "; for (i = 0; i<size; i++) cout << ob2[i] << " "; cout << endl; cout << "Addition: "; ob3 = ob1 + ob2; cout << ob3 << endl; cout << "Subtraction: "; ob3 = ob1 - ob2; cout << ob3; cout << endl << endl; getch();}