- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(x) \
if(x != NULL) \
{ \
x->Release(); \
x = NULL; \
}
#endif
#define SAFE_DELETE(a) if( (a) != NULL ) delete (a); (a) = NULL;
#ifndef SAFE_ARRAY_DELETE
#define SAFE_ARRAY_DELETE(x) \
if(x != NULL) \
{ \
delete[] x; \
x = NULL; \
}
#endif
#define SAFE_FREE( p ) if( p ) { free( p ) ; p=NULL ; }
Я вот все никак не могу забыть старый код из доков макрософт по COM, а также из книги Андре Ла Мота.
Два макроса до сих пор висят среди доков на сайте мс (по коду догадаетесь какие):
http://msdn.microsoft.com/ru-RU/library/windows/desktop/dd743946(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/dd940435(v=vs.85).aspx
Лучше. Она хотя бы не так забагована, как макросы, перечисленные выше ;)
да, также как и в T * operator = (T *p) {
поддержки const корректности не хватает
T * operator = (T *p) { не безопасен с точки зрения исключений и не хваает такого же оператора, только копирования
> поддержки const корректности
Логично
> не безопасен с точки зрения исключений
Зачем AddRef и Release будут кидать исключения? Они ведь даже не крестоблядские...
Моя DLL, че хочу то и делаю. Соглашения о вызовах и исключениях не зафиксированы, поэтому я всегда могу написать свои и следовать им.
А вот COM это не та вещь, в которой допустимы вольности. Не нравятся правила COM'а - мути свою аналогичную технологию, но не создавай людям батхерты, называя это COM'ом.
К тому же "Exceptions aren't allowed to flow across a COM interface boundary. Because there is no binary contract for C++ exceptions, COM cannot marshal them from one thread to another.". Т.е. с COM объектом из соседнего процесса так уже не поработаешь.
P.S. Исключение в Release равносильно исключению в деструкторе.
AddRef увеличивает счетчик использований на 1.
Release уменьшает, и удаляет объект, если счетчик достиг нуля.
QueryInterface позволяет получить другой интерфейс по его GUID'у.
http://msdn.microsoft.com/en-us/library/windows/desktop/bb761722(v=vs.85).aspx
fxd
Основы макроёбства - не жалеть скобок в выражениях и do { ... } while (0) в стейтментах, чтобы потом об этом не жалеть ;)
Сравни и Второе, естественно, смотрится привычней и интуитивней.
Лучше так:
Нет, не лучше. Этот вариант забагуется на примере Романа, равно как и просто { ... }. Конструкцию с if(0){}else{...} юзают не в таком случае, а когда макросом пытаются эмулировать какой-нибудь foreach или особый if.
Емнип других способов замутить макрос, ведущий себя как вызов void функции кроме do { ... } while(0) и нет.
Пример использования if(0){}else для foreach и\или if ? if(0){}else - если это не работает, то зачем так делают?
Оно работает, но семантика получается как у любой другой управляющей конструкции - if/for/while и т.п. Вот для эмуляции новых подобных конструкций оно юзабельно. Для эмуляции void функций - нет.
> Пример использования if(0){}else для foreach
В Qt'шной реализации foreach'а for завернут в if(0){}else чтобы переменные, описанные в for'е не вылезали наружу из-за ебанутого скопинга в msvc6. Если интересно, а искать исходники кютихи влом - могу выложить сюда этот кусочек.
Не, спасибо. Я видел. Тот щё гонокод. Хуже только BOOST_FOREACH
А вообще же тот, кто уже обжёгся, ставит фигурные скобки при каждом удобном случае, даже вокруг единственного оператора: Разве так не надёжнее?
А я ставлю их в нетривиальных случаях - более одного уровня вложенности. Примерно так:
А я потом понять не мог, почему у меня память течь начала, да и ещё в промышленных масштабах, по 3 мб на одну отрисовку
Скобки то само-собой надежнее. Но согласитесь: лучше написать макрос (а лучше вообще не писать их лишний раз без причины ;) так, чтобы он адекватно работал во всех контекстах, чем объяснять в документации как именно нужно его юзать, и надеяться, что ее будут читать...
> А вообще же тот, кто уже обжёгся, ставит фигурные скобки при каждом удобном случае
Обжегшись на молоке дуют на воду... Проблема то в том, что макрос через жопу написан. А пофиксить пытаются последствия.
P.S. Кстати макросы написаны неправильно, нужно больше do { ... } while(0).
Ужоснах какой-то. В чем смысл такой функции? Оптимизация путем устранения лишней проверки? Так один хер все в страхе будут проверять, и проверка вернется, правда вместо одного места она будет размазана по всему коду ровным слоем...
Это фича!