допустим, имеется у меня класс, с методом по распарсиванию определенных данных, результат работы которого используется далее в программе объектом другого класса.
подскажите, как можно улучшить следующий кусок кода:
int main(){
try{
CParser parser;
std::auto_ptr<CData> pData = parser.parse();
//--далее работаем с pData
//--которая должна
//--быть валидной
}catch(const CSyntaxError &e){
//invalid flow of program
std::cout << e.what() << std::endl;
}
return 0;
}
в вышеприведенном куске кода не нравится то, что мы ловим исключение CSyntaxError, и re-throw-им его, а выше, в самой main() еще раз ловим его. налицо нерациональность.
логика такова, что при выбрасывание исключения в методе CParser::parser() уже является достаточным для завершения проги. но как-то писать в этом методе здесь exit(-1); рука не поднимается.
у кого-нибудь есть идеи по поводу улучшения этого подхода? просто нужно мозгам моим перестроиться на нужную стезю, а сам не могу непредвзято посмотреть на это все.
жду подсказки, спасибо.
Здравствуйте, Аноним, Вы писали:
А>в вышеприведенном куске кода не нравится то, что мы ловим исключение CSyntaxError, и re-throw-им его, а выше, в самой main() еще раз ловим его. налицо нерациональность.
перевыбрасывание исключение делается через throw без параметра, а не так, как ты написал. Поскольку ты ловишь по ссылку, то ты можешь поймать исключение производного класса, и при твоем способе "перевыброса" произойдет срезка (т.е. создастся _новый_ объект класса CSyntaxError) вместо настоящего перевыброса оригинального исключения.
А>логика такова, что при выбрасывание исключения в методе CParser::parser() уже является достаточным для завершения проги. но как-то писать в этом методе здесь exit(-1); рука не поднимается.
Завершение проги — забота проги, а не парсера.
Разделение ответственности (и ограничение ответственности одного класса, a.k.a single responsibility principle) — это правильный путь.
Парсер не должен заниматься остановом программы, он должен просто рапортовать об ошибках парсинга.
Так что все нормально.
Тем более что позже тебе понадобиться грохать программу и по другим исключениям, кроме парсинга (например, потому что не найден файл с данными или там сокет не создался), и твой catch преобразуется.
А>у кого-нибудь есть идеи по поводу улучшения этого подхода? просто нужно мозгам моим перестроиться на нужную стезю, а сам не могу непредвзято посмотреть на это все. А>жду подсказки, спасибо.
Идея одна — когда дизайнишь класс, думай о том, как он будет использоваться в другой проге или в другой ситуации.
Даже если этот класс будет использоваться только в этой одной программе.
Этим ты сильно упростишь себе и разработку, и дальнейшую поддержку.
Гораздо проще жить, зная, что парсер только парсит, чем помнить, что парсер и парсит, и иногда грохает программу, и иногда на машинке крестиком...
You will always get what you always got
If you always do what you always did
Re[2]: пробегитесь по коду, пожалуйста.
От:
Аноним
Дата:
08.06.08 18:25
Оценка:
Здравствуйте, jazzer, Вы писали:
J>перевыбрасывание исключение делается через throw без параметра, а не так, как ты написал. Поскольку ты ловишь по ссылку, то ты можешь поймать исключение производного класса, и при твоем способе "перевыброса" произойдет срезка (т.е. создастся _новый_ объект класса CSyntaxError) вместо настоящего перевыброса оригинального исключения.
исправил. сделал просто throw; я правильно понял, что теперь проблемы с слайсингом не будет?
далее, все вашы пояснения разобрал и понял. спасибо за такой подробный ответ.
Здравствуйте, Аноним, Вы писали:
А>исправил. сделал просто throw;
Я вот только не понял зачем ловить исключение и просто бросать его дальше? Ведь если его не ловить, то эффект будет тем же? Оно просто пойдёт вверх по иерархии вызова ф-ций.
std::auto_ptr<CData> CParser::parse(){
std::auto_ptr<CData> pData(new CData());
//do dirty work. (парсим в общем)
//в случае обнаружения некорректности синтаксиса данных, кидаем исключение CSyntaxErrorreturn pData;
Точка входа не изменяется.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[2]: пробегитесь по коду, пожалуйста.
От:
Аноним
Дата:
09.06.08 08:45
Оценка:
Здравствуйте, Mr. None, Вы писали:
MN>Точка входа не изменяется.
поясните, пожалуйста. и почему она должна была меняться? вообще, к чему вы про entry point? извините, недопонял.
Здравствуйте, php-coder, Вы писали:
PC>Здравствуйте, Аноним, Вы писали:
А>>исправил. сделал просто throw;
PC>Я вот только не понял зачем ловить исключение и просто бросать его дальше? Ведь если его не ловить, то эффект будет тем же? Оно просто пойдёт вверх по иерархии вызова ф-ций.
Ну, иногда бывает, что надо перевыбросить только одно какое-то исключение, а с другими еще что-то сделать/проигнорировать.
Тут без catch никак не обойтись.
Типа так:
Здравствуйте, jazzer, Вы писали:
PC>>Я вот только не понял зачем ловить исключение и просто бросать его дальше? Ведь если его не ловить, то эффект будет тем же? Оно просто пойдёт вверх по иерархии вызова ф-ций.
J>Ну, иногда бывает, что надо перевыбросить только одно какое-то исключение, а с другими еще что-то сделать/проигнорировать.
Это понятно.
J>Тут без catch никак не обойтись.
В данном примере он не нужен. Я лишь осведомился, в курсе ли об этом автор.
Здравствуйте, jazzer, Вы писали:
PC>>В данном примере он не нужен. Я лишь осведомился, в курсе ли об этом автор. J>Ты чего ругаешься, я ж согласился с тобой
Я просто хотел быть уверенным, что меня правильно поняли.
Re[8]: пробегитесь по коду, пожалуйста.
От:
Аноним
Дата:
09.06.08 10:40
Оценка:
php_coder
согласен.
ps: осталось понять что имел ввиду Mr. None в посте выше про точку входа и что тем самым он хотел пояснить.
Аноним 310 wrote:
> MN>Точка входа не изменяется. > поясните, пожалуйста. и почему она должна была меняться? вообще, к чему
Вроде всё понятно. Из твоего кода нужно удалить строки
try{
}catch (const CSyntaxError &e){
throw e;
}
и всё.
> вы про entry point? извините, недопонял.
Он про то, что в твоём посте названо "точка входа:".
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай