Упростим задачу, вот код с дописанными комментариями
# include <iostream>
# include <iomanip>
# include <cstdlib>
using namespace std;
class Array
{
friend istream &operator>>(istream &input, Array &a); // ввод данных в класс Array через cin
friend ostream &operator<<(ostream &output, const Array &a);// вывод данных класса Array через cout
public:
//конструктор выделяет место под нужное колличество элементов массива
//по умолчанию на 10 элементов
Array (int arraySize=10)
{
size=(arraySize>0 ? arraySize : 10);
ptr=new int[size];
for (int i=0;i<size;i++)
ptr[i]=0;
}
//конструктор копии Array (чтобы можно было сделать array1(array2))
Array (const Array &arrayToCopy)
:size (arrayToCopy.size)
{
ptr=new int[size];
for (int i=0;i<size;i++)
ptr[i]=arrayToCopy.ptr[i];
}
//деструктор
~Array()
{
delete [] ptr;
}
//возвращает размер массива
int getSize() const
{
return size;
}
//перегрузка оператора присваивания для класса Array
Array operator=(const Array &right)
{
if (&right!=this)
{
if (size!=right.size)
{
delete [] ptr;
size=right.size;
ptr=new int [size];
}
for (int i=0;i<size;i++)
ptr[i]=right.ptr[i];
}
return *this;
}
//определения равны ли два массива
bool operator==(const Array &right) const
{
if (size!=right.size)
return false;
for (int i=0;i<size;i++)
if (ptr[i]!=right.ptr[i])
return false;
return true;
}
//определение не равенства двух массивов
bool operator!=(const Array &right) const
{
return !(*this==right);
}
//возможность обращения к нужному элементу массива
//возвращает указатель на этот элемент чтобы обеспечить присваивание
//НЕ РАБОТАЕТ
Array operator [](int subscript)
{
if (subscript<0 || subscript >=size)
{
cerr<<"\nError: Subscript "<<subscript
<<" out of range"<<endl;
exit (1);
}
return ptr[subscript];
}
//возможность обращения к нужному элементу массива для const даных
Array operator[](int subscript) const
{
if (subscript<0 || subscript>=size)
{
cerr<<"\nError: Subscript "<<subscript
<<" out of range"<<endl;
exit (1);
}
return ptr[subscript];
};
private:
int size; //размер массива
int *ptr; //указатель на данные массива
};
istream &operator>>(istream &input, Array &a)
{
for (int i=0;i<a.size;i++)
input>>a.ptr[i];
return input;
};
ostream &operator<<(ostream &output, const Array &a)
{
int i;
for (i=0;i<a.size;i++)
{
output<<setw(12)<<a.ptr[i];
if ((i+1)%4==0)
output<<endl;
}
if (i%4!=0)
output<<endl;
return output;
};
int main()
{
Array integers1(7);
Array integers2;
cout<<integers1;
integers1[4]=100;//не изменяет integers1[4] так как функция получает копию
cout<<integers1;
return 0;
}
Код компилируется, но беда в другом - при перегрузке операторов передаются копии. При попытке написать например
Array& operator[](int subscript) const
я получаю ошибку что у меня там мол дальше возвращается же ссылка на int данные и мол так нельзя. Пишу
int &operator[](int subscript) const
опять же таки всё компилируется но блин опять же таки нужный объект класса не модифицируется (это видно по выводу данных до и после попытки заменить 4 элемент массива в main).
Добавлено позже:А, тьфу, я редактировал функцию что для const данных, тогда там просто int &operator[](int subscript) const и всё будет работать. Короче вот так тогда должно быть:
# include <iostream>
# include <iomanip>
# include <cstdlib>
using namespace std;
class Array
{
friend istream &operator>>(istream &input, Array &a); // ввод данных в класс Array через cin
friend ostream &operator<<(ostream &output, const Array &a);// вывод данных класса Array через cout
public:
//конструктор выделяет место под нужное колличество элементов массива
//по умолчанию на 10 элементов
Array (int arraySize=10)
{
size=(arraySize>0 ? arraySize : 10);
ptr=new int[size];
for (int i=0;i<size;i++)
ptr[i]=0;
}
//конструктор копии Array (чтобы можно было сделать array1(array2))
Array (const Array &arrayToCopy)
:size (arrayToCopy.size)
{
ptr=new int[size];
for (int i=0;i<size;i++)
ptr[i]=arrayToCopy.ptr[i];
}
//деструктор
~Array()
{
delete [] ptr;
}
//возвращает размер массива
int getSize() const
{
return size;
}
//перегрузка оператора присваивания для класса Array
Array &operator=(const Array &right)
{
if (&right!=this)
{
if (size!=right.size)
{
delete [] ptr;
size=right.size;
ptr=new int [size];
}
for (int i=0;i<size;i++)
ptr[i]=right.ptr[i];
}
return *this;
}
//определения равны ли два массива
bool operator==(const Array &right) const
{
if (size!=right.size)
return false;
for (int i=0;i<size;i++)
if (ptr[i]!=right.ptr[i])
return false;
return true;
}
//определение не равенства двух массивов
bool operator!=(const Array &right) const
{
return !(*this==right);
}
//возможность обращения к нужному элементу массива
//возвращает указатель на этот элемент чтобы обеспечить присваивание
int &operator [](int subscript)
{
if (subscript<0 || subscript >=size)
{
cerr<<"\nError: Subscript "<<subscript
<<" out of range"<<endl;
exit (1);
}
return ptr[subscript];
}
//возможность обращения к нужному элементу массива для const даных
int operator[](int subscript) const
{
if (subscript<0 || subscript>=size)
{
cerr<<"\nError: Subscript "<<subscript
<<" out of range"<<endl;
exit (1);
}
return ptr[subscript];
};
private:
int size; //размер массива
int *ptr; //указатель на данные массива
};
istream &operator>>(istream &input, Array &a)
{
for (int i=0;i<a.size;i++)
input>>a.ptr[i];
return input;
};
ostream &operator<<(ostream &output, const Array &a)
{
int i;
for (i=0;i<a.size;i++)
{
output<<setw(12)<<a.ptr[i];
if ((i+1)%4==0)
output<<endl;
}
if (i%4!=0)
output<<endl;
return output;
};
int main()
{
Array integers1(7);
Array integers2;
cout<<integers1;
integers1[4]=100;//не изменяет integers1[4] так как функция получает копию
cout<<integers1;
return 0;
}
Сейчас только в main протестирую всё ли работает теперь как положено.
Добавлено позже:HoRRoR,читаю, просто этот совет твой не для всех функций помог, ну да я уже "добил" этот класс и теперь вроде перегрузка операторов стала понятнее.
Добавлено позже:Небольшой вопрос на тему правильно ли я понял:
если у меня идёт перегрузка оператора "внутри" класса и она возвращает что-то (в данном случае ссылку на данные типа int) то я пишу так:
int operator[](int subscript) const
{
if (subscript<0 || subscript>=size)
{
cerr<<"\nError: Subscript "<<subscript
<<" out of range"<<endl;
exit (1);
}
return ptr[subscript];
};
А если ничего не возвращает или возвращает указатель *this то я вместо того чтобы написать void должен писать имя класса, так?