Помогите исправить код...
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Код должен вычислять ср. значение 3 массивов, но при вводе размера массива где есть 2 (Например: Строк-2, столбцов 1), выдает ошибку:
Спасибо, модератор, что поправил оформление кода. А то совсем тоскливо, когда движок форума еще «ошибок» добавляет.
Modern, во-первых, удалять массивы нужно через
delete[]
.Во-вторых, ты перепутал букавки, которые у тебя определяют размеры массивов.
Вообще, все эти действия с массивами лучше оформить через функции. Тогда и кода будет меньше, и отлаживать проще.
А еще лучше завернуть массив в класс. Тогда голова не будет болеть и о том, какие размеры у того или другого массива.
На досуге прикинул как это будет выглядеть с классом. Получилось довольно длинно. Но зато по честному. Для этой конкретной задачи половину методов можно было не писать.
Для трассировки добавил макрос TR.
Это первый вариант.
А вот второй вариант для функции main. Им нужно заменить код между «началом» и «концом»:
Интересно, что если в векторе не зарезервировать место под объекты, то при каждом следующем вызове emplace_back уже существущие в векторе объекты будут копироваться (т.е. вызывается конструктор копии для нового объекта, а затем деструктор для старого объекта со всеми вытекающими последствиями). Я как-то не ожидал такого поведения от вектора ((
Хотелось бы услышать замечания по качеству кода. (Знаю, что надо было бы разделить код на три файла: matrix.h, matrix.cpp и main.cpp. Но для краткости пусть будет так.)
А какое поведение ожидалось? Чувствую, что хотелось бы перемещение чтобы использовал вектор? Но тогда и код нужно писать правильно. Конструктор перемещения вектора будет перемещать элементы контейнера только в случае, если конструктор перемещения элементов гарантирует, что из него не вылетит исключение. Другими словами, сделай
и не греши на вектор, он здесь не виноват.
Как в рекламе Сникерса: «Ну, что, лучше?.. Лучше.» Конструктор перемещения подхватился. На счет тонкости с noexcept не знал ((
Интересно, из каких соображений сделано такое ограничение. Как бы обычный конструктор и конструктор копии, которые могут выкидывать исключения, для контейнеров STL кошерно. А конструктор перемещения — нет.
Вообще-то я ожидал большего, чем конструктор перемещения. Где-то читал, что при инициализации контейнера сразу выделяется память под несколько элементов (то ли 12, то ли 16), а потом, при добавлении, когда ёмкости не хватает, происходит увеличение ёмкости в 1.5 раза, соответственно с перераспределением памяти. Это раз. И еще почему-то думал (тоже вроде где-то читал), что в самом контейнере хранятся указатели на объекты нетривиальных типов. Т.е. при расширении контейнера копируются только указатели, а не сами объекты.
Такое распространено во многих фреймворках, например, владеющие контейнеры в C++Builder, но в стандартной библиотеке вектор хранит само объекты.
Для соблюдения требований строгой гарантии безопасности исключений. Если перемещающий конструктор выкидывает исключения, то такую гарантию соблюсти невозможно, но можно обеспечить такую гарантию с помощью копирования.
Всё равно не понятно. Что имеется ввиду под «строгой гарантии безопасности исключений»?
Мы добавляем объект в вектор. Вектор расширяется, при этом создаются копии старых элементов, а сами эти элементы уничтожаются. Копии элементов могут создаваться либо конструктором копирования, либо конструктором перемещения. Какая разница где возникнет исключение: в конструкторе копирования или в конструкторе перемещения? Причем интуиция подсказывает, что вероятность получить исключение больше именно в конструкторе копирования (при выделении памяти, например).
Оно и имеется ввиду. Это означает, что объект либо меняется полностью, либо не меняется вообще, если возникло исключение. Если конструктор перемещения объекта в векторе может выбросить исключение, то такую гарантию дать невозможно, поэтому используется копирование.
Огромная. Если используется перемещение, то часть объектов опустошена при переносе, а часть — нет. Это нарушает гарантии. При копировании, если выбросилось исключение, мы можем просто почистить всё и выбросить его дальше, при этом вектор останется не измененный, соблюдая гарантию.
При копировании плевать вылетит исключение или нет. Вектор может обеспечить строгую гарантию. А вектору откуда знать вылетит исключение из конструктора перемещения или нет? Если потенциально оно может оттуда вылететь, то значит перемещение использовать нельзя, т.к. если исключение вылетит, то строгая гарантия будет нарушена. А как узнать может ли вылететь исключение из конструктора перемещения? Правильно, посмотреть на noexcept.
Понял. Спасибо за разъяснение.
Да без проблем. )))