перезадание переменной типа “класс”

191
22 марта 2017, 18:30

Не совсем понимаю, как работать с классами в си

Допустим, у меня есть такой простой класс:

class matrix{
    public:
    int *X;
    matrix(int N){
        X= new int [N];
    }
    ~matrix(){
        delete [] X;
    }
}

И вот я задаю новый экземпляр этого класса:

matrix a(5);

Как мне теперь перезадать его? Я делаю так:

a.~matrix();
a = matrix(7);

Правильно? И теперь самое интересное - в этом классе есть ещё функция

SET(int I, int x){
    X[I]=x;
}
int main(){
    matrix a(7);
    a.SET(0,3); //тут работает
    a.~matrix();
    a = matrix(9);
    a.SET(0,3);//если есть эта строка то не просто вылетает программа,
               //так ещё и без сообщения об ошибке
    a.SET(1,3);// а вот эта работает хорошо
return 0;
}

Что я не учёл или сделал не так?

Answer 1

То, что вы называете перезаданием, на самом деле простое присваивание. Вам в вашем классе нужно определить оператор присваивания и конструктор копирования. Вообще, это справедливо для любого сколь-нибудь нетривиального класса...

Я бы делал так:

class matrix {
public:
    matrix(int N)
    {
        x = new int[N];
        n = N;
        for(int i = 0; i < n; ++i)
            x[i] = 0;
    }
    matrix(const matrix& m)
    {
        x = new int[m.n];
        n = m.n;
        for(int i = 0; i < n; ++i)
            x[i] = m.x[i];
    }
    matrix& operator=(const matrix& m)
    {
        if (this == &m) return *this;
        delete[] x;
        x = new int[m.n];
        n = m.n;
        for(int i = 0; i < n; ++i)
            x[i] = m.x[i];
        return *this;
    }
    ~matrix()
    {
        delete[]x;
    }
private:
    int *x;
    size_t n;
}

Вернее, я бы делал не так, но для простоты давайте именно так.

У вас все неприятности из-за отсутствия операторов присваивания и копирующего конструктора.

Теперь вот это

a.~matrix();
a = matrix(7);

вам не нужно, просто

a = matrix(7);

достаточно (оператор сам освободит память).

a.~matrix();
a = matrix(9);
a.SET(0,3);//если есть эта строка то не просто вылетает программа,
           //так ещё и без сообщения об ошибке

Тут у вас не работало, ибо получалось следующее: удаление массива. Создание временной матрицы с 9 элементами. Из-за отсутствия копирующего конструктора и оператора присваивания - простое присваивание адреса (а не создание нового массива). Уничтожение временной матрицы с освобождением памяти (указатель на которую остается в матрице a). Попытка записи в уже освобожденную память...

Все просто. Главное - пишите все конструкторы, присваивание и деструктор.

Можно еще и перемещающие писать, но это уже потом, сначала разберитесь с этим...

Еще два замечания.
В SET проверяйте выход индекса за границы массива.
НЕ ЗЛОУПОТРЕБЛЯЙТЕ БОЛЬШИМИ БУКВАМИ В ИМЕНАХ :)

READ ALSO
Компаратор для set [требует правки]

Компаратор для set [требует правки]

Подскажите пожалуйста как написать свой компаратор для setЭто будет использоваться в целях спортивного программирования

313
Перевод const char* в const u_char*

Перевод const char* в const u_char*

Я работаю с двумя функциями из сторонних библиотекОдна возвращает const char*, а другая принимает const u_char*

216
Не могу понять ,как создать пустой список указателей на объект через std :: vector

Не могу понять ,как создать пустой список указателей на объект через std :: vector

Создать пустой список указателей на объекты класса Круг, используя коллекции языка С++ (например, std::vector<T>)

186