пробегитесь по коду, пожалуйста.
От: Аноним  
Дата: 08.06.08 17:53
Оценка:
привет, олл.

допустим, имеется у меня класс, с методом по распарсиванию определенных данных, результат работы которого используется далее в программе объектом другого класса.
подскажите, как можно улучшить следующий кусок кода:
 
    std::auto_ptr<CData> CParser::parse(){
        std::auto_ptr<CData> pData(new CData());
        try{
            //do dirty work. (парсим в общем)
            //в случае обнаружения некорректности синтаксиса данных, кидаем исключение CSyntaxError
        }catch (const CSyntaxError &e){
            throw e;
        }
        return pData;
    }

точка входа:
    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); рука не поднимается.
у кого-нибудь есть идеи по поводу улучшения этого подхода? просто нужно мозгам моим перестроиться на нужную стезю, а сам не могу непредвзято посмотреть на это все.
жду подсказки, спасибо.
Re: пробегитесь по коду, пожалуйста.
От: jazzer Россия Skype: enerjazzer
Дата: 08.06.08 18:13
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>в вышеприведенном куске кода не нравится то, что мы ловим исключение CSyntaxError, и re-throw-им его, а выше, в самой main() еще раз ловим его. налицо нерациональность.


перевыбрасывание исключение делается через throw без параметра, а не так, как ты написал. Поскольку ты ловишь по ссылку, то ты можешь поймать исключение производного класса, и при твоем способе "перевыброса" произойдет срезка (т.е. создастся _новый_ объект класса CSyntaxError) вместо настоящего перевыброса оригинального исключения.

А>логика такова, что при выбрасывание исключения в методе CParser::parser() уже является достаточным для завершения проги. но как-то писать в этом методе здесь exit(-1); рука не поднимается.


Завершение проги — забота проги, а не парсера.
Разделение ответственности (и ограничение ответственности одного класса, a.k.a single responsibility principle) — это правильный путь.
Парсер не должен заниматься остановом программы, он должен просто рапортовать об ошибках парсинга.
Так что все нормально.

Тем более что позже тебе понадобиться грохать программу и по другим исключениям, кроме парсинга (например, потому что не найден файл с данными или там сокет не создался), и твой catch преобразуется.

А>у кого-нибудь есть идеи по поводу улучшения этого подхода? просто нужно мозгам моим перестроиться на нужную стезю, а сам не могу непредвзято посмотреть на это все.

А>жду подсказки, спасибо.

Идея одна — когда дизайнишь класс, думай о том, как он будет использоваться в другой проге или в другой ситуации.
Даже если этот класс будет использоваться только в этой одной программе.
Этим ты сильно упростишь себе и разработку, и дальнейшую поддержку.
Гораздо проще жить, зная, что парсер только парсит, чем помнить, что парсер и парсит, и иногда грохает программу, и иногда на машинке крестиком...
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

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; я правильно понял, что теперь проблемы с слайсингом не будет?

далее, все вашы пояснения разобрал и понял. спасибо за такой подробный ответ.
Re[3]: пробегитесь по коду, пожалуйста.
От: php-coder Чехия http://slava-semushin.blogspot.com
Дата: 08.06.08 19:00
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>исправил. сделал просто throw;


Я вот только не понял зачем ловить исключение и просто бросать его дальше? Ведь если его не ловить, то эффект будет тем же? Оно просто пойдёт вверх по иерархии вызова ф-ций.
Re: пробегитесь по коду, пожалуйста.
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 09.06.08 02:19
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>привет, олл.


[skipped]

Так:
 
std::auto_ptr<CData> CParser::parse(){
std::auto_ptr<CData> pData(new CData());
//do dirty work. (парсим в общем)
//в случае обнаружения некорректности синтаксиса данных, кидаем исключение CSyntaxError
return pData;


Точка входа не изменяется.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[2]: пробегитесь по коду, пожалуйста.
От: Аноним  
Дата: 09.06.08 08:45
Оценка:
Здравствуйте, Mr. None, Вы писали:

MN>Точка входа не изменяется.

поясните, пожалуйста. и почему она должна была меняться? вообще, к чему вы про entry point? извините, недопонял.
Re[4]: пробегитесь по коду, пожалуйста.
От: jazzer Россия Skype: enerjazzer
Дата: 09.06.08 09:53
Оценка:
Здравствуйте, php-coder, Вы писали:

PC>Здравствуйте, Аноним, Вы писали:


А>>исправил. сделал просто throw;


PC>Я вот только не понял зачем ловить исключение и просто бросать его дальше? Ведь если его не ловить, то эффект будет тем же? Оно просто пойдёт вверх по иерархии вызова ф-ций.


Ну, иногда бывает, что надо перевыбросить только одно какое-то исключение, а с другими еще что-то сделать/проигнорировать.
Тут без catch никак не обойтись.
Типа так:
catch(const MyException&)
{
  throw;
}
catch (...)
{
  // ignore
}
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: пробегитесь по коду, пожалуйста.
От: php-coder Чехия http://slava-semushin.blogspot.com
Дата: 09.06.08 10:00
Оценка:
Здравствуйте, jazzer, Вы писали:

PC>>Я вот только не понял зачем ловить исключение и просто бросать его дальше? Ведь если его не ловить, то эффект будет тем же? Оно просто пойдёт вверх по иерархии вызова ф-ций.


J>Ну, иногда бывает, что надо перевыбросить только одно какое-то исключение, а с другими еще что-то сделать/проигнорировать.


Это понятно.

J>Тут без catch никак не обойтись.


В данном примере он не нужен. Я лишь осведомился, в курсе ли об этом автор.
Re[6]: пробегитесь по коду, пожалуйста.
От: jazzer Россия Skype: enerjazzer
Дата: 09.06.08 10:04
Оценка:
Здравствуйте, php-coder, Вы писали:

PC>В данном примере он не нужен. Я лишь осведомился, в курсе ли об этом автор.


Ты чего ругаешься, я ж согласился с тобой
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[7]: пробегитесь по коду, пожалуйста.
От: php-coder Чехия http://slava-semushin.blogspot.com
Дата: 09.06.08 10:07
Оценка:
Здравствуйте, jazzer, Вы писали:

PC>>В данном примере он не нужен. Я лишь осведомился, в курсе ли об этом автор.

J>Ты чего ругаешься, я ж согласился с тобой

Я просто хотел быть уверенным, что меня правильно поняли.
Re[8]: пробегитесь по коду, пожалуйста.
От: Аноним  
Дата: 09.06.08 10:40
Оценка:
php_coder
согласен.

ps: осталось понять что имел ввиду Mr. None в посте выше про точку входа и что тем самым он хотел пояснить.
Re[3]: пробегитесь по коду, пожалуйста.
От: . Великобритания  
Дата: 09.06.08 19:09
Оценка:
Аноним 310 wrote:

> MN>Точка входа не изменяется.

> поясните, пожалуйста. и почему она должна была меняться? вообще, к чему
Вроде всё понятно. Из твоего кода нужно удалить строки
try{
}catch (const CSyntaxError &e){
   throw e;
}

и всё.

> вы про entry point? извините, недопонял.

Он про то, что в твоём посте названо "точка входа:".
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: пробегитесь по коду, пожалуйста.
От: Аноним  
Дата: 09.06.08 19:13
Оценка:
все понял, спасибо. все исправил уже давно =)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.