|
|
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
ErVПри каждом случае, когда хоть одна процедура возвращает код неудачи, дальнейшее выполнение функции невозможно. ОДнако все равно надо будет освободить созданные интерфейсы и т.д. Бряками. :) Еслиб вайла не было, то выход через вызов функции освобождения ресурсов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 09:52 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
blindedВяло что-то, вяло обсуждаем... Надо подлить маслица в огонь: А вот что делать, ежели ошибка произошла в одном потоке, а обработать ее надо в другом.Ну в сишах при асинхронном вызове делегата возникшее исключение у тебя вылетит в вызывающем потоке при вызове EndInvoke ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 11:39 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
daevaorn ErV ОДнако все равно надо будет освободить созданные интерфейсы и т.д.а если применить RAII? Тогда проблемы в ручном освобождениии не будет LPDIRECTXFILEDATA - это, к сожалению, кривой Майкрософтовский макрос, за которым скрывается IDirectXFileData* - т.е. COM обьект. Все COM обьекты в примере инициализируются путем передачи в функцию значений типа IDirectXFileData**. - Т.е. указатель на указатель на интерфейс. Поэтому, по-моему, этот вариант "не катит", и не выйдет "удобно" использовать смарт поинтеры (хотя я могу ошибаться). Akh Бряками. :) Разве бряки пройдут вот тут, вне цикла?: Код: plaintext 1. 2. 3. 4. 5. 6. 7. Akh Еслиб вайла не было, то выход через вызов функции освобождения ресурсов. Расшифруйте, пожалуйста, я вас не понял. У меня слово "вайп" упорно ассоциируется с MMORPG. :-\ (переиграл чуть-чуть в свое время) ЗЫ. Майкрософтвоская программа в аналогичной ситуации использует goto... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 15:10 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
ErV 1. Разве бряки пройдут вот тут, вне цикла?: 2. Akh Еслиб вайла не было, то выход через вызов функции освобождения ресурсов. Расшифруйте, пожалуйста, я вас не понял. У меня слово "вайп" упорно ассоциируется с MMORPG. :-\ (переиграл чуть-чуть в свое время) ЗЫ. Майкрософтвоская программа в аналогичной ситуации использует goto... 1. Видел. Но замолчал тему, т.к. можно закрывать учитывая только открытые. Тем более все равно можно свести ко второму случаю :) 2. Например, такое Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Почему я такой вариант предложил, потому-что вспомнилось, что когда-то использвал такой вид: int func_close_safe(Param1 lpDXFileEnum, ..., int ret) { SAFE_RELEASE(lpDXFileEnum); SAFE_RELEASE(lpDXFileData); SAFE_RELEASE(lpDXFileApi); return ret; }; int func_work() { while (SUCCEEDED(hr)){ //ProcessTemplate(lpDXFileData); //waiting until TID_D3DRM_FRAME arrives----------------------- const GUID* lpType; hr = lpDXFileData->GetType(&lpType); //hr=E_FAIL; if (hr!=...) return func_close_safe(lpDXFileEnum, ..., error); } [/SRC] ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 15:24 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
ErV 1. Разве бряки пройдут вот тут, вне цикла?: 2. Akh Еслиб вайла не было, то выход через вызов функции освобождения ресурсов. Расшифруйте, пожалуйста, я вас не понял. У меня слово "вайп" упорно ассоциируется с MMORPG. :-\ (переиграл чуть-чуть в свое время) ЗЫ. Майкрософтвоская программа в аналогичной ситуации использует goto... 1. Видел. Но замолчал тему, т.к. можно закрывать учитывая только открытые. Тем более все равно можно свести ко второму случаю :) 2. Например, такое Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Почему я такой вариант предложил, потому-что вспомнилось, что когда-то использвал такой вид: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 15:25 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
Akh[quot ErV] 2. Например, такое Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Тут такая небольшая проблема есть. В том файле, откуда я это выдирал, подобных функций было не меньше десятка (та, что я привел, была просто наиболее простая), и работали они все немного по-разному. Далее, часть интерфейсов является локальными переменными, т.е. функция очистки не подойдет, так как вложенные функции на C++ писать нельзя. И, ИМХО, если делать для каждой такой функции класс будет немного нерационально... хотя, конечно, можно попробовать найти точки пересечения и т.д., но просто (мне кажется) код от этого не станет понятнее... И ещё. Обратите внимание на throw в блоке catch. До этой функции происходит 5и-6и уровневый вызов функции, работающих по похожему принципу, но с другими интерфейсами, которые, однако, аналогично инициализируются, и при этом инициализация может пройти неудачно... в этом случае return int можно быть коряво... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 16:43 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
ErV daevaorn ErV ОДнако все равно надо будет освободить созданные интерфейсы и т.д.а если применить RAII? Тогда проблемы в ручном освобождениии не будет LPDIRECTXFILEDATA - это, к сожалению, кривой Майкрософтовский макрос, за которым скрывается IDirectXFileData* - т.е. COM обьект. Все COM обьекты в примере инициализируются путем передачи в функцию значений типа IDirectXFileData**. - Т.е. указатель на указатель на интерфейс. Поэтому, по-моему, этот вариант "не катит", и не выйдет "удобно" использовать смарт поинтеры (хотя я могу ошибаться). ну это совсем не проблема, пока правда boost::smart_com нет, но написать простой враппер для COM интерфейсов можно легко, было бы желание. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 16:50 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
daevaorn ну это совсем не проблема, пока правда boost::smart_com нет, но написать простой враппер для COM интерфейсов можно легко, было бы желание. Ну, не знаю... там интерфейсы в определенном порядке освобождаться должны... и, по-моему, в ряде случаев все-таки может быть быстрее использовать исключения или даже goto... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 18:01 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
Голенков Владимирб.м. неудача при попытке захвата ресурса в конструкторе как раз тот случай?Вот тут согласен. Сложный конструктор который может упасть во время собственно конструирования без исключений упасть не сможет вообще. blindedНет, конено можно написать и так template <typename T> class Stack { public: ... int size() const; const T& read() const { assert(size()); return ...; } }; Жить можно, все равно при отладке вылезетА еще, в случае работы со стеком, можно проверять не пуст ли стек перед очередным pop(). Это будет еще больше писанины, зато при дальнейшем сопровождении программы будет сразу видно что в этом месте мы сто процентно не будем читать из пустого стека и этой ошибки не появится вообще. Ты скажешь: "Ага! Каждый раз делать проверку? Это еще больше писать прийдется!" Да, верно писать прийдется больше, но это будет намного проще сопровождать. Вот представь что ты берешь чужой код сопровождать и видишь там десяток mystack.pop() разбросаных внутри функции. Ты уверен что предыдущий автор ЭТОЙ функции, убедился что автор класса стека действительно бросает исключение из pop() при пустом стеке? Не уверен? Значит ты сам пойдешь искать исходники класса стека и исследовать как там реализована проверка на пустоту стека. Вот берем например QT. Смотрим документацию: QT 4.2.2 T QStack::pop () Removes the top item from the stack and returns it. This function assumes that the stack isn't empty.Скажи мне пожалуйста упадет такой код или не упадет, а если упадет то как именно упадет? Код: plaintext 1. 2. 3. 4. 5. А теперь сравни с этим кодом: Код: plaintext 1. 2. 3. 4. 5. MasterZivНу ты стойкий перец! Упорно меня не хочешь понимать. Решения ОТЛИЧАЮТСЯ тем, что при RETURN тебе надо будет написать обработку ошибок НА ВСЕХ ПРОМЕЖУТОЧНЫХ УРОВНЯХ в стеке вызовов, приведших к вызову данной функции. Для того и созданы exceptions чтобы с этим бороться. Если бы была разница только в синтаксисе, никому было бы это не нужно.А кому нужно чтобы ошибка проходила несколько промежуточных уровней? Вот это еще один момент который меня просто убивает в идеалогии исключений. Зачем мне исключение сгенерированое драйвером железа если я пишу гуй? Ошибка произошедшая на одном уровне должна быть обработана на этом же уровне или в крайнем случае на следующем уровне. Поднимать ее выше можно, но не правильно. А то в итоге ты можешь доподниматься до того что рисуя клиента к базе данных, и в диалоге "сохранить запись, да/нет" ты будешь обрабатывать ошибки tcpip стека. Либо будешь ловить родителя всех исключений, какой-ниубдь std::exception или ему подобное и обрабатывать общую ошибку без разбора что там в действительности произошло. MasterZiv(скриптовые языки не берем)А почему это "скриптовые языки не берем"? Чуешь что счет окажется не в пользу исключений? :) На скриптовых мы пишем не меньше чем на компилируемых. А чем дальше, тем больше. Мне вообще кажется, что будущее за скриптами а не компилируемыми исходниками. Так что скриптовые тоже надо учитывать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 19:19 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
ErVКасательно исключений и COM. Как можно вот такое реализовать без исключений и goto ? .... При каждом случае, когда хоть одна процедура возвращает код неудачи, дальнейшее выполнение функции невозможно. ОДнако все равно надо будет освободить созданные интерфейсы и т.д. А почему без goto? В твоем коде заменяем макрос и try/catch на: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 19:32 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
Показываю как надо, чтоб не жевать сопли с обработкой ошибок по всему коду template <class T> class DirectXPrt // Ценноссть только в деструкторе { public: typedef T* Pointer; virtual ~DirextX() { if (ptr) SAFE_RELEASE(ptr); } // This garbage only for backward compatibility Pointer operator->() { assert(ptr); return ptr; } Pointer getPtr() { assert(ptr); return ptr; } operator T*() { assert(ptr); return ptr; } protected: DirectXPtr() { ptr = 0; } DirectXPtr(Pointer* p) { ptr = p; } Pointer* ptr; }; class DirectXFilePtr : public DirectXPtr<LPDIRECTXFILE> { public: DirectXFilePtr(); DirectXFileEnumPtr makeFileEnum(LPSTR s); void registerTemplates(LPVOID, size_t); // из исходника не ясен 2 параметр }; class DirectXFileEnumPtr : public DirectXPtr<LPDIRECTXFILEENUMOBJECT> { public: typedef DirectXPtr<LPDIRECTXFILEENUMOBJECT> Parent; DirectXFileDataPtr getNext(); private: friend class DirectXFilePtr; DirectXFileEnum(Pointer p) : parent(p) {} }; class DirectXFileDataPtr : public DirectXPtr<LPDIRECTXFILEDATA> { public: typedef DirectXPtr<LPDIRECTXFILEDATA> Parent; GUID getType() const { if (!id) load(); return *id; } const std::string& getString() const { if (!id) load(); return name; } private: friend class DirectXFileEnumPtr; DirectXFileDataPtr(Pointer p) : parent(p), id(0), name("") {} void load(); const GUID* id; std::string nane; } // Классы исключений сами допишите, не маленькие class DirectXFatalException : public std::exception { }; class DirectXEnumException : public std::exception { }; class DirectXDataException : public std::exeption {}; //------------------------------------------------------------------------------------------ DirectXFilePtr::DirectXFilePtr() { if (FAILED(DirectXFileCreate(&ptr)) throw DirectXFatalException(); } DirectXFileEnumPtr DirectXFilePtr::makeFileEnum(LPSTR s) { LPDIRECTXFILEENUMOBJECT p; if ( FAILED(this->CreateEnumObject((LPVOID)s, DXFILELOAD_FROMFILE, &eptr.get())) ) throw DirectXEnumException(); return DirectXFileEnumPtr(p); } void DirectXFilePtr::registerTemplates(LPVOID p, size_t sz) { if(FAILED(this->RegisterTemplates(p. sz))) throw DirectXFatalException(); } DirectXFileDataPtr DirectXFileEnumPtr::getNext() { LPDIRECTXFILEDATA p; if( FAILED(this->GetNextDataObject(&p)) ) throw DirectXEnumException() ; return DirectXFileDataPtr(p); } void DirectXFileDataPtr::load() { if ( FAILED(fileData->GetType(&id))) throw DirectXDataException(); DWORD size; if ( FAILED(lpDXFileData->GetName(0, &dwNameSize)) ) throw DirectXDataException(); char buf[128]; if ( FAILED(lpDXFileData->GetName(buf, &size))) throw DirectXDataException() name = buf; } //------------------------------------------------------------------------------------------ // Зато какая красота в прикладном коде void LoadLevelFromX(LPCSTR lpszXFile) { // Ну это не мое char szbuf[128]; char szbuf2[128]; ExtractFileName(szbuf2, lpszXFile); sprintf(szbuf, "%s%d", szbuf2, rand());//GetTickCount()); // А это уже мое, такое даже секретарша поймет DirectXFilePtr fileApi; fileApi.registerTemplates((LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES)); DirectXFileEnumPtr fileEnum = fileApi.makeFileEnum(lpszFile); try { while(true) { DirectXFileDataPtr fileData = fileEnum.getNext(); if ( fileData.getType() == TTD__D3DMRFrame && ) { if (fileData.getName() == "SceneRoot") { _D("SceneRoot found\n"); GameLevel_LoadLevel_RootLoop(lpDXFileData); } } else _D ("Not TID_D3DRMFRAME\n"); } } catch ( DirectXEnumException e) { ; } } // А это не мое //-------- // Если молния в лоб угодит, // Значит просто подставлен лоб, // Или волосы действуют словно магнит, // Или тело похоже на столб... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 21:05 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
blindedПоказываю как надо, чтоб не жевать сопли с обработкой ошибок по всему коду ... По-моему, вариант как с goto, так и с исключениями был короче. И проще. И LPDIRECTXFILEDATA это не класс, а typedef, точнее даже макрос #define LPDIRECTXFILEDATA IDirectXFileData* где IDirectXFileData - Com интерфейс. ИМХО, в этом варианте код запутался, фактически остался тем же, особых плюсов я не вижу... ИМХО, нерационально делать вокруг каждого Интерфейса обертку... ЗЫ. Склоняюсь к варианту с goto... А также к мысли найти и пристукнуть того, кто сказал, что использование goto - "плохой стиль". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 22:46 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
Эта краткость обманчмва. Когда надо будет написать ну одну такую функцию обертка сыграет свою роль ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2007, 23:47 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
Не заметил - было здесь или нет, но главное, с моей точки зрения, преимущество исключений в том, что они раскручивают стек корректно. Это значит что ошибку можно безопасно передать на любой уровень. Производительность исключения не шибко роняют, если роняют вообще - желающие могут легко написать тест и сравнить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 00:03 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
blindedКогда надо будет написать ну одну такую функцию обертка сыграет свою роль Когда будет использоваться 50 разных интерфейсов, написание обертки для каждого замедлит работу... (у вас в примере ряд функции имеют надстройки над стандартными функциями) Опять же, это ИМХО... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 00:39 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
ErV blindedКогда надо будет написать ну одну такую функцию обертка сыграет свою роль Когда будет использоваться 50 разных интерфейсов, написание обертки для каждого замедлит работу... (у вас в примере ряд функции имеют надстройки над стандартными функциями) Опять же, это ИМХО... а почему нельзя написать обобщенную обертку для схожих интерфейсов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 00:46 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
blindedПоказываю как надо, чтоб не жевать сопли с обработкой ошибок по всему кодуВот за такой код я и не люблю С++. В примере ErV четко видны блок инициализации, блок работы и блок деструктор. А в этом наборе темплейтов и классов найти что-либо даже с десятого взгляда не представляется возможным. Это тот самый стиль программирования "лапша" за который ругают оператор goto. Код в котором может разобраться только автор и только в течении ближайшей недели после написания. Добавляем в него исключения и уже сам черт ногу сломит разбираясь как и куда там передается управление, что за чем вызывается. Священая война против goto началась с утверждения что goto перекидывает управление далеко-далеко по коду. Исключения делают тоже самое, но не по линейному коду а по стеку вызовов. daevaornа почему нельзя написать обобщенную обертку для схожих интерфейсов?Можно. Проблема только в том, что это очень сложно. Сложно сделать удобную обертку для чего бы то ни было. Чтобы суметь ее сделать, надо на уровне эксперта разбираться в том для чего делается обертка, а в этом случае обертка уже обычно не нужна. А если ты не эксперт - ты сделашь вместо обертки уродца годного только для сиюминутной задачи. Потащишь этого уродца во второй проект - чуть-чуть облагородишь его, но изначальное уродство заложеное не знанием предмета будет оставаться очень-очень долго. С течением лет это уродство станет почти не заметным, но будет оставаться. В любом случае, чтобы сделать хорошую обертку нужно несколько лет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 01:22 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
White Owl daevaornа почему нельзя написать обобщенную обертку для схожих интерфейсов?]Показываю как надо, чтоб не жевать сопли с обработкой ошибок по всему кодуВот за такой код я и не люблю С++. В примере ErV четко видны блок инициализации, блок работы и блок деструктор. А в этом наборе темплейтов и классов найти что-либо даже с десятого взгляда не представляется возможным. Это тот самый стиль программирования "лапша" за который ругают оператор goto. Код в котором может разобраться только автор и только в течении ближайшей недели после написания. Добавляем в него исключения и уже сам черт ногу сломит Можно. Проблема только в том, что это очень сложно. Сложно сделать удобную обертку для чего бы то ни было. Чтобы суметь ее сделать, надо на уровне эксперта разбираться в том для чего делается обертка, а в этом случае обертка уже обычно не нужна. А если ты не эксперт - ты сделашь вместо обертки уродца годного только для сиюминутной задачи. Потащишь этого уродца во второй проект - чуть-чуть облагородишь его, но изначальное уродство заложеное не знанием предмета будет оставаться очень-очень долго. С течением лет это уродство станет почти не заметным, но будет оставаться. В любом случае, чтобы сделать хорошую обертку нужно несколько лет.[/quot] Ну я не так радикально предлагаю. Всего лишь proxy класс с "правильным" деструктором, который в случае необходимости вызовет release ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 01:27 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
daevaorn ErV blindedКогда надо будет написать ну одну такую функцию обертка сыграет свою роль Когда будет использоваться 50 разных интерфейсов, написание обертки для каждого замедлит работу... (у вас в примере ряд функции имеют надстройки над стандартными функциями) Опять же, это ИМХО... а почему нельзя написать обобщенную обертку для схожих интерфейсов? Наверное можно, я же не изучал эту библиотеку, да и изучать никакого желания. Все знания извлечены из приведенного автормо куска кода. Потом библиотека написана несолько в ином стиле. хотя бы одно то что производящие методы возвращают код ошибки а указатель на созданный объект записывается в переменную переданную по адресу, не дает возможности безопасно ее обернуть. Но игра стоит свеч, ежели посмотреть на "клиентский код" то можно заметить что там вообще указателей нет. Нет места для потенциальной ошибки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 09:10 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
White Owl blindedПоказываю как надо, чтоб не жевать сопли с обработкой ошибок по всему кодуВот за такой код я и не люблю С++. В примере ErV четко видны блок инициализации, блок работы и блок деструктор. А в этом наборе темплейтов и классов найти что-либо даже с десятого взгляда не представляется возможным. Это тот самый стиль программирования "лапша" за который ругают оператор goto. Код в котором может разобраться только автор и только в течении ближайшей недели после написания. Ну кому же чужой код-то нравится, это понятно. А вот что касается лапши - ну не согласен, категорически, каждый класс имеет свою отвественностьи все ясно и понятно, есть файл с объектами, есть перечисление по нему, элемет данных. У каждого класса свой конструктор и деструктор... И вообще это все должно быть разнесено по разным файлам и даже библиотекам... И потом на вкус и цвет ... У меня вообще один знакомый есть у него подход оценка качества ПО совсем простая - работает и ладно. White Owl Добавляем в него исключения и уже сам черт ногу сломит разбираясь как и куда там передается управление, что за чем вызывается. Священая война против goto началась с утверждения что goto перекидывает управление далеко-далеко по коду. Исключения делают тоже самое, но не по линейному коду а по стеку вызовов. Проблема есть, но совсем не в этой области. Как правило код писанный для себя очень плохо задукоментирован, и никогда не знаешь точно какого исключения ждать. White Owl daevaornа почему нельзя написать обобщенную обертку для схожих интерфейсов?Можно. Проблема только в том, что это очень сложно. Сложно сделать удобную обертку для чего бы то ни было. Чтобы суметь ее сделать, надо на уровне эксперта разбираться в том для чего делается обертка, а в этом случае обертка уже обычно не нужна. А если ты не эксперт - ты сделашь вместо обертки уродца годного только для сиюминутной задачи. Потащишь этого уродца во второй проект - чуть-чуть облагородишь его, но изначальное уродство заложеное не знанием предмета будет оставаться очень-очень долго. С течением лет это уродство станет почти не заметным, но будет оставаться. В любом случае, чтобы сделать хорошую обертку нужно несколько лет. Не, не несколько лет. Чтобы первую версию написать месяц, ну и полгодика в эксплуатации вытащат наруже большую часть недостатков. Тут вопрос такой стоит ли овчинка выделки? Если сделать и забыть, то по-видимому нет. А вот есжели придется сталкиваться с подобными задачами достаточно часто или еще того хуже придется сопровождать один проект несколько лет, тады ой. А что касается уродства сего упражнения, дык я энтой библиотеки в глаза не видел, все наваял исключительно глядя в представленный пример, да и времени то потратил - пару часов, в течении которых еще и поужинать успел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 09:58 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
blinded Проблема есть, но совсем не в этой области. Как правило код писанный для себя очень плохо задукоментирован, и никогда не знаешь точно какого исключения ждать. Ну, не знаю... (далее ИМХО) на меня хорошее влияние оказала книга об XP программировании, и я стараюсь писать код так, чтобы документация к нему не требовалась, равно как и комментарии... (на документацию нужно будет дополнительное время, её все равно надо будет переписывать, и фактически, там будет дублирование кода программы в словесном виде...) Образцом "хорошего" кода для меня на данный момент является Qt. Там логичный стиль, и, в принципе, в том, что там получается, разобраться не очень сложно. К плохому коду отношу то, что творит майкрософт в своих примерах к DirectX SDK, например. Разобраться можно, но там как раз обертки очень старательно используются, и в результате, нужно сидеть довольно долго, чтобы понять логику работы оберток (на изучение работы которых уходит большая часть времени) вместо того, чтобы сразу заняться использованием изучаемого API.. А вот есжели придется сталкиваться с подобными задачами достаточно часто или еще того хуже придется сопровождать один проект несколько лет, тады ой. По-моему, тогда легче будет написать скелет-функцию или скелет-класс, в котором будут использоваться ключевые моменты, а потом плодить от него потомков. Но не оборачивать каждый интерфейс (просто не вижу в этом смысла - это и так уже готовый обьект, ИМХО, оборачивать его ещё раз будет пустой тратой времени), а воплотить в базовом классе/функции основные используемые алгоритмы... А что касается уродства сего упражнения, дык я энтой библиотеки в глаза не видел, все наваял исключительно глядя в представленный пример, да и времени то потратил - пару часов, в течении которых еще и поужинать успел. Это подраздел DirectX - DirectXFile, если вам интересно. Примеров по нему в SDK почти нет. Обертка в данном случае неудобна так как постоянно будет требоваться доступ к переменной, хранящей указатель на интерфейс (например IDirectXFile** и т.д.), который будет засунут, скорее всего, куда-нибудь в private. Сделать с этим ничего нельзя, так как это такая реализация API, исходный код которого не доступен, и которое, к тому же, является системным компонентом. ЕСЛИ бы этого не было, то обертку можно было бы легко написать. Но так как это есть, то потребуется либо куча friend'ов, либо вынести оборачиваемый класс в public либо писать кучу оборачивающих двухстрочных функций для каждого метода исходного интерфейса, а это, по-моему, не самый лучший вариант, так как все удобство обертки сведет к нулю... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 11:13 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
Мы несколько отклонились от темы. Вообще-то разговор шел об исключениях. И мне кажется что при правильном их использовании код значительно упрощается. Во всяком случам получившаяся LoadLevelFromХ выглядит значительно менее устрашающе чем исходный вариант, я не говорю об обертке. А что касается библиотеки DirectX я с ней не пересекаюсь, ибо живу на Unix'e. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 12:33 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
blindedМы несколько отклонились от темы. Вообще-то разговор шел об исключениях. И мне кажется что при правильном их использовании код значительно упрощается. Во всяком случам получившаяся LoadLevelFromХ выглядит значительно менее устрашающе чем исходный вариант, я не говорю об обертке. А что касается библиотеки DirectX я с ней не пересекаюсь, ибо живу на Unix'e. Простите, исходный вариант использовал исключения - макрос HRCHECK бросал производный мой собсвтенный класс исключения, который нес в себе информацию об имени функции, строке, и файле, где произошла ошибка... А получившийся ваш вариант (ничего личного) для меня лично выглядит "более устрашающе" по ряду причин... Пример я привел так как меня давно этот вопрос интересовал, и здесь он был "в тему" в том числе как вариант проблемы не обязательно привязанной к DirectX и Win32... Вообще, стандартному C++ , ИМХО, не хватает модели try{...}catch(){..}finally{...}... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 16:06 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
blindedА вот что касается лапши - ну не согласен, категорически, каждый класс имеет свою отвественностьи все ясно и понятно, есть файл с объектами, есть перечисление по нему, элемет данных. У каждого класса свой конструктор и деструктор... И вообще это все должно быть разнесено по разным файлам и даже библиотекам...А там вообще классы нужны? А темплейты? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 17:32 |
|
||
|
Исключения: за и против
|
|||
|---|---|---|---|
|
#18+
White Owl пишет: > это еще один момент который меня просто убивает в идеалогии исключений. > Зачем мне исключение сгенерированое драйвером железа если я пишу гуй? > Ошибка произошедшая на одном уровне должна быть обработана на этом же > уровне или в крайнем случае на следующем уровне. Поднимать ее выше > можно, но не правильно. В рамках обоих техник можно поднимать или не поднимать ошибки до любого уровня. Поднимается ошибка или нет - зависит от предметной области и правильности реализации софта. > А почему это "скриптовые языки не берем"? А потому что серьезные проекты на них не пишут. Ну ладно, фиг с ними, пусь будут. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.03.2007, 22:59 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=34379162&tid=2029270]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
160ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
83ms |
get tp. blocked users: |
2ms |
| others: | 204ms |
| total: | 488ms |

| 0 / 0 |
