А знаете ли вы что...? (Или программистские типы ;))

Модератор: Модераторы разделов

sdk
Бывший модератор
Сообщения: 210

А знаете ли вы что...?

Сообщение sdk »

А знаете ли вы, что...

Программисты на C++ ну очень часто пишут код типа:

Код: Выделить всё

MyClass::~MyClass()
{
    if(my_pointer) delete my_pointer;
}

А ведь на самом деле, этот if совершенно не нужен! :)
Достаточно написать

Код: Выделить всё

MyClass::~MyClass()
{
    delete my_pointer;
}


А все потому, что они думают, что delete-у нельзя подсовывать нулевой указатель. Фигня! Можно! :)
Определено стандартом:
Оператор delete 0 (старички любят NULL ;) ) просто ничего не делает! :)

Меня это поначалу сразило наповал! :) У меня до сих пор рука дергается написать if(ptr) delete ptr :). Пересиливаю себя и повышаю читабельность кода, параллельно уменьшая количество ассемблерных инструкци :lol:.

Как вам? :)

PS. А у вас есть чего-нибудь из серии "А знаете ли вы что...?" Делитесь! :)
Серьезность - это способ сделать простые вещи сложными.
Если много знать - устанут глаза. Если много спать - то нет.
Нас никому не сбить с пути - нам пофигу куда идти.
:-)
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: А знаете ли вы что...?

Сообщение oav »

Ну да, прыткий какой, открыл Америку :)
Это все замечательно только тогда, когда точно знаешь на каком компиляторе собираешь, вот например visual studio 6,7.0 - буит тебе exception сразу, на гцц древнем таже фигня.

Ну, и пара примеров по теме "А знаете ли Вы что...":

Удаление вектора указателей на POD типы без написания функтора:

Код: Выделить всё

for_each( v.begin(), v.end(), ptr_fun(operator delete) );


Тоже самое, но удаление указателей на любые типы, причем с исправленной ситуацией о ub:

Код: Выделить всё

struct DeleteObject
{
    template<typename T>
    void operator()(const T* ptr) const
    {
        (void)sizeof(T);
        delete ptr;
    }
};

...

for_each( v.begin(), v.end(), DeleteObject() );


Или еще более кошерно, при примеру Струструпа:

Код: Выделить всё

struct delete_object
{
    template<typename T>
    T* operator()(T *ptr) const
    {
         delete ptr;
         return 0;
    }
};

...
std::vector<foo*> v;
std::transform(v.begin(), v.end(), v.begin(), delete_object());

т.е. в итоге ты не только удалил все элементы но и обнулил все значения в векторе - проще отловить обращение по нулевому указателю :)

В если по уму: то надо конечно юзать для такого boost::shared_ptr и не парить себе мозги, если позваляют требования к зависимостям проекта конечно...
Спасибо сказали:
Аватара пользователя
Sparky
Сообщения: 604
Статус: core dumped
ОС: Plan 9

Re: А знаете ли вы что...?

Сообщение Sparky »

А разве не if(!my_pointer) delete my_pointer?
Блог
--------------------

GCS/M/MU/P/IT/E d- s: a- C++(+++) UBL++ P->-- L+++$ E- W+++$ N* o? K? w>--
O M-@ V- PS@ PE+ Y+ PGP+ t 5 X R* tv-->- b++ DI? D>+ G e+(++) h--- r+ y++
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: А знаете ли вы что...?

Сообщение oav »

(Sparky @ Пятница, 10 Декабря 2004, 19:32) писал(а):А разве не if(!my_pointer) delete my_pointer?

Нет, не прав:

If(!expression)
проверяет что expression равно нулю.
if( expression)
проверяет что expression не ноль.

Удалять указатель имеет смысл только если (грубо конечно, там может быть и обычный мусор) не ноль - т.е. указывает на выделенную память.
Спасибо сказали:
sdk
Бывший модератор
Сообщения: 210

Re: А знаете ли вы что...?

Сообщение sdk »

oav, реальные штуки :). Особенно первая :thumbsup: Частенько буду пользоваться.
А про delete 0, я специально написал что это постановлено стандартом :). А ежели всякие там компилеры сему стандарту не следуют, то какого хрена на них ровняться? ;)
Даешь хорошие компилеры в массы! ;)
Серьезность - это способ сделать простые вещи сложными.
Если много знать - устанут глаза. Если много спать - то нет.
Нас никому не сбить с пути - нам пофигу куда идти.
:-)
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: А знаете ли вы что...?

Сообщение oav »

А ежели всякие там компилеры сему стандарту не следуют, то какого хрена на них ровняться? wink.gif
Даешь хорошие компилеры в массы! wink.gif

Твоиб слова на Богу в уши (с) народное :)
К сожалению, чаще всего, нет возможности перехода на более новый компилятор (такой как vc7.1, gcc 3.4 ) из-за наследственности старого кода, который не переписать, ни исправить не представляется возможным. реже встречается принципиальная позиция начальства - мол, только тул XXX и не версии выше!...эх, вот и приходиться..
oav добавил в 11.12.2004 13:40
По поводу использования первого функтора: лучше использовать boost::shared_ptr - _намного_ лучше: меньше писать, меньше отлаживать. Вообще думать не надо о том, что объект выделен динамически, "ручной" сборщик мусора, блин :)

Например:

Код: Выделить всё

typedef boost::shared_ptr<Foo> FooPtr;
typedef std::vector< FooPtr > VFoos;

VFoos vf;

vf.push_back( FooPtr( new Foo ));
vf.push_back( FooPtr( new Foo ));
vf.push_back( FooPtr( new Foo ));
...
//удаляем нафиг вектор и осовобождаем память:
vf.clear();
Спасибо сказали:
Аватара пользователя
Xenon
Бывший модератор
Сообщения: 359
ОС: Debian

Re: А знаете ли вы что...?

Сообщение Xenon »

О, наконец-то человеческий тред на нашем форуме :)
Спасибо - Оптимизированый кодинг рулит :thumbsup:
Спасибо сказали:
sdk
Бывший модератор
Сообщения: 210

Re: А знаете ли вы что...?

Сообщение sdk »

oav:
Ну не знаю, у меня на gcc-3.3 все пахает. И, если я не ошибаюсь, я пробовал это и на 3.2. delete ptr работает отлично.
Насчет vc молчу, потому как не знаю.

А boost - это библиотечка? Надо будет погуглить.... Спасибо за наводку! :)

PS. Кстати, я где-то выше писал "delete 0" -- извиняюсь, надо было "delete ptr, где ptr - нулевой указатель".
Серьезность - это способ сделать простые вещи сложными.
Если много знать - устанут глаза. Если много спать - то нет.
Нас никому не сбить с пути - нам пофигу куда идти.
:-)
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: А знаете ли вы что...?

Сообщение oav »

мм, буст? ну да, "библиотечка" :)
Скажем так: буст - это прототип будущего С++. Многие библиотеки, которые в него входят сейчас вскоре будут в namespace std :) (некоторые уже туда собсна попали)

буст: www.boost.org

зы. Если кто-то считает себя достаточно квалифицированным в С++, прошу идти на буст.орг и убеждаться в обратном =)) (шутка, но имеющая долю правды для меня)

ззы. Если есть какие-нибудь вопросы по С++ и иже с ним, чем могу, помогу...
Спасибо сказали: