
Ned Ogl
23.10.2016
23:53:09
я видел деструкторы в дизассемблинге, но поленился почитать
ткчто спросил на всякий
просто я хочу понять, надо ли вызывать освобождающий динамически взятую память деструктор перед throw?
если throw не обрабатывают, произойдёт утечка, я проверял, деструктор не вызовется

Google

Kirill
23.10.2016
23:56:39
Вопрос непонятен. Уточни.

Ned Ogl
23.10.2016
23:58:00
ну смотри, я разрабатываю класс матрицы. шаблонный. допустим произошла исключительная ситуация: пользователь по какой-то причиние умножил матрицы неподходящего размера. получить результат мы не можем, ибо операция алгебраически не определена. тогда я throw Exception();
что если пользователь умножал их не в блоке try{}catch()
эксепшн вздёрнет программу по SIGTERM

Kirill
23.10.2016
23:58:51
Тебя это не касается.

Ned Ogl
23.10.2016
23:58:56
и память под объект утечёт (проверял валгриндом)
то есть, нет смысла делать delete перед throw?

Kirill
23.10.2016
23:59:23
Тебе нужно только обеспечить корректное освобождение ресурсов при уничтожении объекта.

Ned Ogl
24.10.2016
00:00:25
хорошо, а где вообще прописана зона ответственности проектировщика классов? я не встречал. понятно, что все ситуации я не предусмотрю, но я хочу чтобы юзеры не плевались от моего класса и могли легко писать приложения, ага

Kirill
24.10.2016
00:00:37
Если твоя матрица представлена внутри как обычный динамический массив, то в конструкторе ты выделяешь под него память, а в деструкторе освобождаешь ее.

Ned Ogl
24.10.2016
00:00:41
что мне надо для этого сделать?

Kirill
24.10.2016
00:01:50
Как создаешь экземпляры матриц?

Google

Ned Ogl
24.10.2016
00:02:53
template <class T>
Matrix<T>::Matrix(const int _rows, const int _cols):
rows(_rows),
cols(_cols){
#ifdef DEBUG
std::cout << "Constructor (int, int) called\n";
#endif
if ((_rows < 1) || (_cols < 1)) throw Matrix<T>::ExceptionWrongInitialParams();
data = new T[rows*cols];
for (int i = 0; i < rows*cols; data[i++] = (T)0);
}
template <class T>
Matrix<T>::Matrix(const Matrix<T> ©):
rows(copy.rows),
cols(copy.cols){
#ifdef DEBUG
std::cout << "Copy constuctor called\n";
#endif
data = new T[rows*cols];
for (int i = 0; i < cols*rows; data[i] = copy.data[i], i++);
}
других вариантов пока нет

Kirill
24.10.2016
00:04:58
Я спросил, как ты матрицы перемножаешь.
И где деструктор?

Ned Ogl
24.10.2016
00:05:14
Как создаешь экземпляры матриц?
И где деструктор?
template <class T>
Matrix<T>::~Matrix(){
#ifdef DEBUG
std::cout << "Destructor called!\n";
#endif
delete [] data;
}
перемножая создаю первым конструктором матрицу, забиваю значениями, возвращаю
вот и всё
если размер неверный, throw

Kirill
24.10.2016
00:06:20
Ок. Я имел в виду, что непонятен сценарий использования класса, который вызывает утечку.

Ned Ogl
24.10.2016
00:06:35
а, ну банально, смотри
template <class T>
bool Matrix<T>::isSquare(){
return (cols == rows);
}
template <class T>
T Matrix<T>::getTrack(){
if (this->isSquare()){
T track = (T)0;
for (int i = 0; i < cols; track += (*this)[i][i], ++i);
return track;
}
delete [] data;
throw ExceptionSquareOperationForNonSquare();
}
вот есть такие 2 функции
а я делаю где-то в программе так:
Matrix <int> A(5,4);
A.getTrack();
вот и всё, взлетает эксепшн "операция для неквадратной матрицы"
к ним же относится определитель, например

Kirill
24.10.2016
00:08:46
Конструкция в цикле это шедевр, конечно. :)

Ned Ogl
24.10.2016
00:09:25
ты не поверишь, чего мне она стоила) раньше i++ стоял во вторых скобках, но это постоянно вызывало undefined behaviour)

Kirill
24.10.2016
00:09:25
А зачем освобождать память где-то еще, кроме деструктора?

Ned Ogl
24.10.2016
00:09:53
так вот в чём дело. если за эксепшном никто не следит, то деструктор не вызывается

Kirill
24.10.2016
00:10:06
Эта функция возвращает сумму диагональных элементов?

Google

Ned Ogl
24.10.2016
00:10:06
и память не освобождается (если система не позаботится о том)
да, это след матрицы)
относится, что логично, только к квадратным

Kirill
24.10.2016
00:11:45
for (std::size_t i = 0; i < _rows; i++)
track += data[i][i];
Так же гораздо понятнее?

Ned Ogl
24.10.2016
00:13:09
ну теперь да, вообще говоря
не поверишь, я поменял, но откатился на старую ветку)

Kirill
24.10.2016
00:13:43
Только вот не помню, откуда компилятор берет информацию о размерности двумерного массива. Безопаснее писать data[i*_rows+j]

Ned Ogl
24.10.2016
00:14:13
оригинальный массив одномерный)

Kirill
24.10.2016
00:14:46
Т.е. ты перегрузил оператор двойные скобки?

Ned Ogl
24.10.2016
00:14:50
дважды

Kirill
24.10.2016
00:15:06
А, читал вчера

Ned Ogl
24.10.2016
00:16:06
наконец разобрался с константными функциями-членами и их комбинацией с this
там интересная лабуда

Kirill
24.10.2016
00:16:47
Вызов delete[] в функции расчета следа это бред полный. После этого объект переходит в неработоспособное состояние.

Vladislav
24.10.2016
00:17:00
к слову, математический след по-английиски это trace а не track

Kirill
24.10.2016
00:17:02
Эта функция вообще должна быть const.

Vladislav
24.10.2016
00:17:13

Ned Ogl
24.10.2016
00:18:14
вообще говоря, я руководствовался той логикой, что раз объект вызвал исключение, он уже неработоспособен и надо стереть память пока не поздно

Google

Ned Ogl
24.10.2016
00:18:32
однако придумал-таки ситуацию, где этого делать не стоит и постирал дилиты
а потом откатился к старой ветке

Kirill
24.10.2016
00:18:38
Нет, это не так

Ned Ogl
24.10.2016
00:18:57
так что спасибо, что внимательно читали и напомнили)

Kirill
24.10.2016
00:20:45
Твой класс предназначен для хранения матриц произвольных размерностей. Ты решил добавить функцию-член для подсчета следа, который определен только для квадратных. У тебя два выбора. Либо ты просто выбрасываешь исключение при вызове этой функции для неквадратной матрицы, либо создаешь подкласс SquareMatrix и уже для него реализуешь эту функцию. Но тогда его конструктор будет другой.
Второй вариант лучше не используй.

Ned Ogl
24.10.2016
00:23:01

Admin
ERROR: S client not available

Kirill
24.10.2016
00:23:53
Хорошее решение.

Ned Ogl
24.10.2016
00:59:55
есть тут кто-нить ещё?

Vladislav
24.10.2016
01:03:15
м?

Ned Ogl
24.10.2016
01:04:24
слушай, я не понимаю, мы же можем вызывать константные методы для неконст объектов, так?
и никаких проблем быть не должно
однако я ловлю тучу проблем при вызове неконстантных методов для неконстантных объектов...
да и вообще тучу говна при вызовах
хз почму
главная проблема вот в чём. я не могу обратиться к this почему-то..

Google

Ned Ogl
24.10.2016
01:07:45
так, я короче повожусь ещё и напишу если че не так будет

Vladislav
24.10.2016
01:08:37
тут, да, чем еще заняться воскресным вечером?)

Ned Ogl
24.10.2016
01:08:55
нахер понедельничную тоску потому что

Vladislav
24.10.2016
01:08:57
не должно быть проблем, а что компилятор пишет?

Ned Ogl
24.10.2016
01:09:14
да я всё ещё со своими двойными скобками, короче

Vladislav
24.10.2016
01:10:07
показывай код)

Ned Ogl
24.10.2016
01:10:16
не, я чуть позже, плиз
тут есть что поправить

Vladislav
24.10.2016
01:10:21
ok

Ned Ogl
24.10.2016
01:28:34
итак, есть константный объект
оператор [] от него возвращает другой константный объект
оператор [] от второго возвращает константный тип
так схуяяле нельзя передавать this в первом операторе второму объекту?
ща буит код

Vladislav
24.10.2016
01:30:12
второй объект должен принимать его как const

Ned Ogl
24.10.2016
01:31:09
http://ideone.com/srjnK3
вот. смотри
в строчке 173 обращаемся к константе
вызывается строчка 135
объект константный!! оператор тоже константный! генерит константный подобъект
хуле ему не нравится?!