Консультация № 139455
07.06.2008, 16:04
0.00 руб.
0 2 2
Здравствуйте уважаемые эксперты.Нужна помощ в решении задач.
Задача 1: Создайте класс защищенного массива, в котором реализована проверка выхода за границы массива. Перегрузите операторы: [ ], =, +, -
(Программа написана, при компилировании ошибок нет, но когда уже введу значения последнего объекта, то выполнение останавливается и выдает ошибку "Debug assertion failed" и перегруженные операции + и - далее не выполняются. см.приложение)

Задача 2: Создайте класс Время, в котором реализованы операции сложения, вычитания, сравнения, ввода и вывод на экран. Возможность конвертации времени из американского формата am (pm): 10:00 pm = 22:00, 12:00 pm =00:00

Приложение:
/*Создайте класс защищенного массива, в котором реализована проверка выходаза границы массива. Перегрузите операторы: [ ], =, +, -, <<, >>*/#include <iostream>#include <cstdlib>#include <conio.h>using namespace std;const int N = 100;class mass{private:int *a;int s;public:mass(){}mass(int size = N){s = size;a = new int [s];for (int i=0; i<size; i++)a[i]=0;}int &operator[] (int i);mass operator+ (mass ob);mass operator- (mass ob);mass operator= (mass ob);friend istream &operator >> (istream&, mass&);friend ostream &operator << (ostream& , const mass &);~mass(){delete [] a;}};int& mass::operator[](int i){if (i<0 || i>4){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 (int i = 0; i<size; i++)cout << ob1[i] <<" ";cout << endl;cout << "Enter elements of the 2nd object: " << endl;for (int i = 0; i<size; i++)cin >> ob2[i];cout << endl;cout << "Second object: ";for (int i = 0; i<size; i++)cout << ob2[i] << " ";cout << endl;cout << "Addition: ";ob3 = ob1 + ob2;cout << ob3;cout << "\nSubtraction: ";ob3 = ob1 - ob2;cout << ob3;getch();}

Обсуждение

Неизвестный
07.06.2008, 22:10
общий
это ответ
Здравствуйте, Белоус Владимир Владимирович!

Все, что я здесь нашёл:

1.
int& mass::operator[](int i){
if (i<0 || i>4){ - видимо должно быть if (i<0 || i>=s){
cout<<"Limits are exceeded\n";
exit(1);
}

2.
В операторах сложения и вычитания может получится Access violation если длина массива, который вы прибавляете больше длины массива, к которому прибавляют.
Лучше так:
for (int i = 0; (i<ob.s || i<s); i++){
....
}

3.
Оператор "равно". Проблема та же, но решение другое.
mass mass::operator=(mass ob){
if (ob.s != s) {
delete [] a;
a = new int[ob.s];
s = ob.s
}
for (int i = 0; i<s; i++){
a[i] = ob.a[i];
}
return *this;
}
давно
Советник
165461
578
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();}
Форма ответа