136 / 107 / 61
Регистрация: 05.02.2012
Сообщений: 241
|
||||||||||||||||
1 | ||||||||||||||||
Класс Матрица05.02.2012, 00:24. Показов 5734. Ответов 23
Метки нет (Все метки)
Вообщем задали мне в универе написать программу для работы с матрицами. Для этого нужно создать класс Матрица. Вообщем я только начал и сделал некоторые наброски(конструкторы и деструкторы)ю
Вообщем кому не трудно проверьте. Заголовочный файл classMatrix.h:
0
|
05.02.2012, 00:24 | |
Ответы с готовыми решениями:
23
Определить базовый класс "Матрица" и класс-потомок "Треугольная матрица" Класс матрица Класс Матрица с++ класс матрица |
404 / 360 / 36
Регистрация: 11.10.2010
Сообщений: 1,907
|
|
05.02.2012, 00:33 | 2 |
Игорь Миронюк, а что именно проверить? В коде вроде бы все нормально.
0
|
136 / 107 / 61
Регистрация: 05.02.2012
Сообщений: 241
|
|
05.02.2012, 01:03 [ТС] | 3 |
Ну, я имею в виду обработку исключений в конструкторе, деструктор, подключение библиотек и пространство имен, стражей и т.п.
0
|
576 / 559 / 47
Регистрация: 16.12.2011
Сообщений: 1,389
|
|
05.02.2012, 03:42 | 4 |
Вроде бы все хорошо.
Только я стандартные заголовочные файлы вынес бы в отдельный файл и подключал уже его. Затем, ограничение на мин. размерность матрицы. Наверное, стоило бы сделать переменные row и col беззнаковыми. И тогда исключение IncorrectSize можно кидать только если row или col равны нулю. Сейчас вы почему-то не даете создать матрицу 1х1, хотя по факту число тоже можно назвать матрицей) Также я бы добавил пустой конструктор (создающий пустую матрицу 0х0 или, например, матрицу 1х1). Ну и жесткая привязка к типу double. Хотя может так и надо, я не знаю всего вашего задания. Если от вас хотят получить контейнер "матрица", то к double не следует привязываться.
1
|
136 / 107 / 61
Регистрация: 05.02.2012
Сообщений: 241
|
|||||||||||||||||||||
05.02.2012, 14:26 [ТС] | 5 | ||||||||||||||||||||
По вашему совету ,I.M., сделал конструктор пустой матицы(0х0). Можете объяснить зачем он нужен. row и col оставил без изменений, посчитал что так будет лучше(вдруг кого-нибудь пробьет попробовать создать матрицу с отрицательными размерами). Стандартные заголовочные файлы вынес в отдельный файл. double по условию задания. Спасибо.
Файл standardHeaderFiles.h:
0
|
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
|
|||||||||||||||||||||
05.02.2012, 14:52 | 6 | ||||||||||||||||||||
если ваш конструктор по умолчанию создает матрицу 0х0, то было бы логично и другим конструкторам позволить это.
например,
Добавлено через 3 минуты по мне standardHeaderFiles.h - лишнее, а писать в заголовках
1
|
576 / 559 / 47
Регистрация: 16.12.2011
Сообщений: 1,389
|
|
05.02.2012, 17:52 | 7 |
Я потому и упомянул о беззнаковых типах, чтобы избежать отрицательных значений.
О пустом конструкторе я написал по аналогии со стандартными контейнерами. Там же не обязательно сразу же задавать размеры будущего массива. Можно создать просто пустой массив. А для этого никакие параметры не нужны. Другой вопрос - что считать пустой матрицей. Логично было бы 0х0. Но если вам так не хочется видеть нули в размерах, то можно сделать 1х1. Про пространства имен в общем заголовке действительно лучше не писать. По поводу необходимости такого заголовочного файла - решайте сами. Я обычно использую подобный файл, поэтому и посоветовал.
1
|
136 / 107 / 61
Регистрация: 05.02.2012
Сообщений: 241
|
||||||||||||||||
05.02.2012, 23:57 [ТС] | 8 | |||||||||||||||
Нестыковку с конструкторами вроде решил. Отрицательные значения отбрасывать не хочу, потому что в будущем вижу такую ситуацию: пользователь вводит отрицательный размер, а программа ему пишет об ошибке. Проблемку с заголовочными файлами и пространством имен не решил, посему прошу подсказать, а то чето совсем запутался.
Дополнил класс действиями +,-,* для матриц; вводом и выводом матрицы; сделал оператор присвоения. Вот что получилось: Заголовочный файл classMatrix.h:
0
|
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
|
|
06.02.2012, 00:16 | 9 |
стоит ли делать для этого исключения в классе? ну хорошо. пусть так...
тогда пользователь может пытаться вводить неверные данные(буквы, например) в матрицу. чем этот случай хуже? тоже исключения? можно. нужно ли? вобщем, если уж вы хотите обрабатывать подобные ошибки, и делать это с помощью исключений, делайте это везде. и надеюсь, когда ваш класс станет более завершенным, вы избавитесь от френдов
0
|
136 / 107 / 61
Регистрация: 05.02.2012
Сообщений: 241
|
|
06.02.2012, 00:52 [ТС] | 10 |
А разве "друзья" это плохо. Просто, на мой взгляд, логично эти действия сделать не в качестве метода класса или может сделать это статическими функциями(а для них перегрузка возможна?). А насчет обработки исключений в конструкторе вы правы, а в случае умножения и т.п. А как насчет инклудов(я не уверен в правильности)?
0
|
576 / 559 / 47
Регистрация: 16.12.2011
Сообщений: 1,389
|
|
06.02.2012, 02:41 | 11 |
Зачем вам френды для сложения, вычитания и умножения? Аналогичный вопрос был бы, объяви вы их не френдами, а статическими. И без этих спецификаторов все будет работать.
По поводу ненужности френдов для перегрузки ввода/вывода в поток не уверен. Лично я, имея не очень большой опыт, видел только такой способ перегрузки << и >>. Поэтому тут я френды бы оставил. Немного не осознал исключение в operator=. В стандартных контейнерах в таком случае происходит обычное копирование с выделением/освобождением памяти, если нужно.
0
|
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
|
|||||||||||
06.02.2012, 17:18 | 12 | ||||||||||
вполне логично. вот и сделайте их всех свободными ф-ми и без всяких френдов.
друзья - это довольно редкая необходимость(и то наверняка найдется способ обойтись без них, если это оправдано), которой в вашем классе (я почему-то уверен) не будет: наверняка у вас будут методы доступа к элементам матрицы
1
|
5 / 5 / 0
Регистрация: 06.02.2012
Сообщений: 19
|
|
06.02.2012, 17:52 | 13 |
замечания, которые сразу бросаются в глаза
1. Очень плохо использовать using дерективы в заголовочных файлах (в вашем случае 6: using namespace std. Краткое пояснение. Я пользуюсь своей функцией sort, она мне очень нравиться, но другие алгоритмы использую из <algorithm> для них я явно прописываю std::name ну или прописал необходимые using объявления. Иными словами моя функция sort никак не пересекается со стандартной. Но стоит мне подключить заголовочник с вашей матрицей, как на весь мой код начнет действовать using деректива всего пространства std и я тут же получу множество конфликтов своей функции sort со стандартной. Я надеюсь, что этот пример пояснил немного, почему это не здорово 2. Конструктор не должен (!) выбрасывать исключений. Это грубейшая ошибка, которая приводит к утечкам памяти. Дело в том, что выбросив исключение из конструктора вы больше не можете гарантировать в каком состоянии находиться объект. 3. В конструкторе по умолчанию вы не выделяете память и зануляете указатель, но в деструкторе обращаетесь к i-тому элементу, чтобы очистить строку. Думаю проблема очевидна Ну и на последок: хорошим тоном проектирования класса является следующее: Весь базовый функционал (необходимый минимум) сделать методами класса, все остальное внешними функциями. Например: если вы поместили нечто в метод класса, то фактически вы обязываете меня пользоваться этим методом, но если вы сделали это нечто отдельным методом, то вы даете мне возможность заменить это своей реализацией. Зачем это нужно: вы можете гарантировать, что ваша реализация самая лучшая во всем мире и что она устроит по точности/скорости всех пользователей вашего класса? И еще, не проще ли было хранить матрицу в виде одномерного массива?
1
|
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
|
|
06.02.2012, 18:11 | 14 |
бред. с чего вы взяли?
нет там такого. память не выделяется до возможной генерации исключения.
этого и не нужно: после раскрутки стека - обьекта нет. о каком состоянии объекта идет речь?
Добавлено через 4 минуты к тому же в конструкторах объектов зачастую выделяется память с помощью оператора new, в результате чего может быть сгенерировано исключение bad_alloc. т.е. по вашему все такие конструкторы - потенциальные бомбы и недопустимы
0
|
5 / 5 / 0
Регистрация: 06.02.2012
Сообщений: 19
|
||||||
06.02.2012, 18:12 | 15 | |||||
а, то есть на внутренние поля память не нужна
// что с объектом? // я был в конструкторе! я работал с внутренними полями! значит память под них выделена! // но где она?
0
|
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
|
|
06.02.2012, 18:21 | 16 |
нет его и не было при генерации исключения.
ни с чем вы не работали и уж тем более никакой памяти на этапе исполнения не выделялось.
0
|
5 / 5 / 0
Регистрация: 06.02.2012
Сообщений: 19
|
|
06.02.2012, 18:26 | 17 |
ну значит я был в конструкторе несуществующего класса и обращался к несуществующим внутренним полям, интересно как
в вашем мире C++ гораздо легче и проще, чем в моем...
0
|
retmas
|
06.02.2012, 18:28
#18
|
0
|
136 / 107 / 61
Регистрация: 05.02.2012
Сообщений: 241
|
||||||||||||||||
07.02.2012, 03:51 [ТС] | 19 | |||||||||||||||
retmas, от друзей избавился, но делать отдельные функции делать не стал, действия с матрицами сделал методами, надеюсь это терпимо.
Felsurt, попытался учесть замечания 1. Думаю что исправил проблему с директивой using(но не уверен) 2. От исключения в конструкторе избавился, от него у меня много проблем 3. Здесь я думаю вы не учли, что у меня цикл и если row = 0, то в цикл мы не входим 4. А на счет методов - черт с ними!!! Можете посоветовать наилучший способ нахождения определителя матрицы. Я почитал в инете, самый быстрый способ методом Гаусса: вначале привести к треугольному виду и тогда определитель равен произведению диагональных элементов; или лучше раскладывать по какой-то строке? А еще думаю сделать конструктор матрицы, полученной из данной вычеркиванием определенной строки и столбца. Такой конструктор, я думаю понадобится для нахожденияминора и алгебраического дополнения, да и в нахождении определителя может понадобится. Вот дополненный класс: Заголовочный файл classMatrix.h:
Файл тестирование класса Teting of the class:
1
|
5 / 5 / 0
Регистрация: 06.02.2012
Сообщений: 19
|
|||||||||||||||||||||||||||||||
07.02.2012, 12:39 | 20 | ||||||||||||||||||||||||||||||
я бы считал определитель рекурсивно через разложение по строке
да, это удобный функционал только его лучше реализовывать не конструктором, а методом класса (getMinor), так будет логичней ну и обычно в заголовочниках пишут так
оператор равно всегда должен возвращать ссылку на объект
это аналогично операторам ввода/вывода, которые так же должны возвращать ссылку на свой левый аргумент, что позволяет писать "конвейеры". в методе element вы проверяете, что индекс не больше допустимого, но не проверяете обратного (меньше допустимого) ну и для удобства, как мне кажется, для доступа к элементам можно было бы перегрузить оператор круглых скобок именно круглых, т.к. оператор квадратных скобок обязан всегда принимать только один аргумент если есть оператор + и оператор =, то почему бы не реализовать оператор +=? (аналогично к остальным операторам) кстати, обычно реализуют оператор = и +=, как методы класса, а оператор + делают внешним реализованным через эти два примерно так
ваш класс задал оператор == и я, как бы того не хотел, теперь не смогу изменить критерий сравнения матриц (потому что среди перегруженный функций предпочтение всегда компилятор отдает методу класса) и если вдруг в моей программе не важно равенство элементов матрицы, а лишь важно равенство их размерностей, то мне придется писать длинное некрасивое условие if всегда, когда понадобиться сравнить объекты а вот если бы вы были чуточку милосердны и подумали о разработчиках, которые, быть может, станут пользоваться вашим классом, то вынесли бы оператор == за его пределы и объявили вообще в отдельном файле и тогда бы я мог его подключить, а мог бы написать свой оператор и все были бы счастливы (ну это не говоря о том, что свой класс, по хорошему, надо поместить в свое пространство имен, тогда можно все в одном файле объявить)
1
|
07.02.2012, 12:39 | |
07.02.2012, 12:39 | |
Помогаю со студенческими работами здесь
20
Класс матрица Класс матрица Класс матрица Класс Матрица Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |