Opened 4 years ago
Closed 4 years ago
#640 closed ожидается проверка (задача сдана)
WW #11
Reported by: | Карнаухов Кирилл | Owned by: | Sokolov Viacheslav |
---|---|---|---|
Component: | WW cpp_io | Version: | 3.0 |
Keywords: | Cc: |
Description
Change History (7)
comment:1 Changed 4 years ago by
Type: | ожидается проверка → ожидаются исправления |
---|
comment:2 Changed 4 years ago by
Type: | ожидаются исправления → ожидается проверка |
---|---|
Version: | 1.0 → 2.0 |
comment:3 Changed 4 years ago by
Type: | ожидается проверка → ожидаются исправления |
---|
16 inline std::ostream &operator<<(std::ostream &out, write_le_int32 given_value) {
Зачем inline, почему не реализовать в .cpp, как обычно?
Классы, от которых не предполагается наследоваться, стоит помечать как final
Лучше избегать совпадения имен аргументов и полей класса, чтобы случайно не ошибиться; конструкции вида x(x) вызывают вопросы (нет ли здесь ошибки). Удобно с помощью code style гарантировать различное именование (например, добавляя уникальный префикс к полям классов)
56 out << "Developer\nName: " << _name << "\n" 57 << "Base Salary: " << _base_salary << "\n" 58 << "Has bonus: " << (_has_bonus ? "+" : "-") << "\n";
здесь посередине может произойти fail, а потом опять все хорошо (место на диске закончилось и тут жен освободилось). В идеале нужно с этим что-то сделать. Например, обернуть в манипулятор, который проверит. По-нормальному же просить stream бросить исключение, как только что-то пошло не так.
Непонятно, почему в приведенном ниже методе ответственность за копирование лежит на нем (почему не передать во владение указатель?)
131 void EmployeeArray::add(const Employee *empl) {
132 _employees.push_back(empl->clone());
133 }
comment:4 Changed 4 years ago by
Type: | ожидаются исправления → ожидается проверка |
---|---|
Version: | 2.0 → 3.0 |
Надеюсь, я нормально использовал try/catch и не набагал в этом.
comment:5 Changed 4 years ago by
Type: | ожидается проверка → ожидаются исправления |
---|
.exceptions(std::istream::failbit)
стоит также badbit перехватывать
Исключение можно принимать по const-ссылке; в случае, если что-то пошло не так, код возврата из main не должен быть 0
62 in.read(&char_value, 1);
можно же просто in.read(char_value)?
(и с write та же история)
Рекомендую посмотреть на https://en.cppreference.com/w/cpp/io/basic_istream/getline
Если хочется что-то свое кинуть, то лучше кидать std::exception. Например, std::logic_error.
177 SalesManager? empl;
178 in >> empl;
179 empl_array.add(empl.clone());
проще:
SalesManager?* empl = new SalesManager?();
in >> *empl;
empl_array.add(empl);
comment:6 Changed 4 years ago by
Type: | ожидаются исправления → ожидается проверка |
---|
comment:7 Changed 4 years ago by
Resolution: | → задача сдана |
---|---|
Status: | assigned → closed |
На самом деле достаточно перехватывать const std::exception& (все стандартные исключениия отнаследованы от этого класса)
Не обратил внимание раньше, но read_and_add дублирует код с std::ifstream &operator>>(std::ifstream &in, EmployeeArray? &arr) , а также явно использует константы 1 и 2, что плохо, потому что при добавлении новых Employee или изменении значений 1,2 на что-то другое придется менять много где. Да и вообще в main оказалась какая-то неуправляющая логика, что тоже плохо.
В выбранной реализации в манипуляторах не нужен friend. Достаточно просто декларации свободной функции.
Лучше сделать конструкторы explicit (нужен ли комментарий, почему?)
Вообще говоря, после манипуляции стоило бы проверять, что она удалась (внутри манипулятора). Сейчас проверяется лишь, что на момент начала работы есть смысл пытаться что-то делать.
В main не хватает проверок успешности выполнения чтения из std::cin
Можно было бы принимать не указатель, а ссылку, тогда и проверка на not null не нужна
по какой причине переменная здесь типа int, а не size_t?
метод copy_this_to не очень удачный, потому что:
вместо этого лучше сделать метод clone:
{{{Employee
{
virtual Employee* clone() const = 0;
} }}}
при этом возикает одна проблема, которая вместе с решением описана здесь: https://stackoverflow.com/questions/15575272/how-to-use-clone-in-c-with-multiple-inheritance-of-abstract-classes
(но так делать сейчас не предлагается, потому что становится сложнее)
метод read_employee выбивается по названию. Может быть, read_textually?
Предполагается ли наличие неименованных сотрудников? Я бы думал, что нет; может быть, сделать так, чтобы в конечных классах логику имени не нужно было бы дублировать?
Инициализацию объекта стоит делать в списке инициализации и инициализировать явно все его поля.