Как в данном случае запретить изменение элементов массива в классе из программы?

170
31 декабря 2018, 01:50
#include <iostream>
using namespace std;
typedef int Mytype;

class CArrayData
{
private:
int size;
Mytype* array;
public:
    CArrayData(int size, Mytype* array) // конструктор класса
    {
    this->array = array;
    this->size = size;
    }

CArrayData::~CArrayData() { // деструктор
    delete[] array;
    size = 0;
}
friend void out(CArrayData &CArray);
};
int main(int argc, char** argv)
{
setlocale(LC_ALL, "russian");
int n;
cout << "Введите размер массива: " << endl;
cin >> n;
Mytype *pm = new Mytype[n];
CArrayData Cl(n, pm);
for (int i = 0; i < n; ++i) {
    pm[i] = Mytype (rand() % 1000)/ 10;
}
out(Cl);
pm[0] = 100500; //здесь первый элемент изменяется на 100500, как это запретить?
    out(Cl);
    cin.get();
    cin.get();
    return 0;
}
void out(CArrayData &CArray)
{
for (int i = 0; i < CArray.size; ++i) {
    cout << CArray.array[i] << endl;
    }
}
Answer 1

Один из вариантов, ввести изменения в классе (заодно исправим ошибки).

class CArrayData {
    const int size;       //размер должен быть костантным
    const Mytype* array;  // для хранения адреса константного обьекта
public:
    // константные обьекты инициализируются только инициализатором конструктора
    CArrayData(const int size, const Mytype* array)
        : size(size), array(array) {}// конструктор класса
    ~CArrayData() { // тут у вас была ошибка допольнительная квалификация
        delete[] array;
    }
    //...
};

В программе же сначала иницализируем массив, а потом присваиваем его адрес константному указателью:(Правка: указателью на константный обьект)

Mytype *p = new Mytype[n];
for (int i = 0; i < n; ++i) {
    p[i] = Mytype (rand() % 1000)/ 10;
}
const Mytype* pm = p;
CArrayData Cl(n, pm);   
pm[0] = 100500; //невозможно изменять
Answer 2

Всё оказалось проще, просто перенёс инициализацию массива в конструктор, вроде больше элементы не меняются

#include <iostream>
using namespace std;
typedef int Mytype;
class CArrayData
{
    int size;
    Mytype* array;  
public:
    CArrayData(int size, Mytype* array) // конструктор класса
    {
        cout << "Constructor\n";
        this->size = size;
        this->array = new Mytype[size];
        for (int i = 0; i < size; ++i) {
            this->array[i] = (rand()%1000)/10;
        }
    }

    ~CArrayData() { 
        cout << "Destructor\n";
        delete[] array;
    }
//--------------------------------------------------------------------------
friend void out(CArrayData &CArray);
};
int main(int argc, char** argv)
{
setlocale(LC_ALL, "russian");
int n;
cout << "Введите размер массива: " << endl;
cin >> n;
Mytype *pm = new Mytype[n];
CArrayData Cl(n, pm);
out(Cl);
pm[0] = 100500;
out(Cl);
cin.get();
cin.get();
return 0;
}
void out(CArrayData &CArray)
{
    for (int i = 0; i < CArray.size; ++i) {
        cout << CArray.array[i] << endl;
    }
}
READ ALSO
Поиск в массиве по компоненту значения (сложный тип)

Поиск в массиве по компоненту значения (сложный тип)

На ночь глядя голова не варит ужеПодскажите как решить следующую проблему самым эффективным (быстрым) способом на C++11, C++14, в общем не на старье...

176
Ширина и высота полей ввода в зависимости от содержимого

Ширина и высота полей ввода в зависимости от содержимого

Нужно задавать высоту QTextEdit в зависимости от кол-ва строк содержимого и если строк нет, то и высота нулеваяТоже самое и для QLineEdit, но для ширины

194
Имена файлов с исходным кодом в C/C++

Имена файлов с исходным кодом в C/C++

Имеются ли какие-нибудь ограничения для имени source-файла в C/C++? (в Java, например, имя source-файла должно совпадать с именем класса в нем)

175
Почему вызывается исключение в stdio_common_vfscanf?

Почему вызывается исключение в stdio_common_vfscanf?

При попытке ввода данных в scanf_s столкнулся с проблемой, которую вызывает исключение в файле stdioh

212