пятница, 31 октября 2008 г.

Qt Creator IDE

На сайте Qt Software можно скачать первую версию кроссплатформенной IDE для разработки на С++. Это может стать чем-то интересным, на мой взгляд.

Видео презентация с сайта Qt:

среда, 22 октября 2008 г.

Лицензионный договор

Появилась интересная статья на тему ведения переговоров с издателем и подписывания договора при продаже своего продукта. Взгляд с точки зрения законодательства стран СНГ.

вторник, 14 октября 2008 г.

explicit override

Чисто виртуальные классы часто используются для передачи callback-интерфейсов между DLL и EXE. Типичный интерфейсный класс выглядит так:
struct IServerCallback {
virtual void OnStart() =0;
virtual void OnStop() =0;
virtual void OnInfo( void* ptr, long cookie ) =0;
}


Тогда мы у себя создаем реализацию, например так:
class CApplication: public IServerCallback {
CApplication();
virtual ~CApplication();

// Some additional functions
// ...

// IServer callback implemetaion
virtual void OnStart();
virtual void OnStop();
virtual void OnInfo( void* ptr, long cookie );
}


Так вот пока что все в порядке. Но иногда находятся нехорошие люди, которые делают интерфейс не полностью виртуальным, а делают пустую реализацию для некоторых функций. Выяснение причин, почему так происходит, выходит за рамки этой статьи. Выглядит тогда callback-интерфейс, например, так:
struct IServerCallback {
virtual void OnStart() =0;
virtual void OnStop() =0;
virtual void OnInfo( void* ptr, long cookie ) {};
}


И все бы хорошо, пока мы случайно не ошибемся в определении функции. Можно ошибиться в названии или написать const void* ptr вместо void* ptr — не суть. А главное в том, что получим неожиданное поведение — наша функция не будет вызываться. Чтобы избежать этого, можно использовать так называемое explicit override. Как следует из названия, нужно просто явно указать какому интерфейсу принадлежит та или иная функция. Выглядеть это будет так:
class CApplication: public IServerCallback {
CApplication();
virtual ~CApplication();

// Some additional functions
// ...

// IServer callback implemetaion
virtual void IServerCallback::OnStart();
virtual void IServerCallback::OnStop();
virtual void IServerCallback::OnInfo( void* ptr, long cookie );
}


Тут, в случае наличия реализации по умолчанию, компилятор выдаст ошибку, что и требовалось. Ошибка будет и в случае, если декларация функции в интерфейсе и в классе различаются.

UPD: Это работает только в компиляторе от Microsoft и не является стандартом.
UPD: В Microsoft, как я и предполагал, ввели данный синтаксис в Managed C++ для явной реализации интерфейсов(подробнее). Но, оказалось, что это частично можно применять в обычном С++.

четверг, 9 октября 2008 г.

multi_index + shared_ptr

В различных контейнерах бывает удобно хранить не сами объекты, а указатели на них. Тут multi_index позволяет использовать shared_ptr с объектом почти так же как будто там хранится сам объект, включая индексирование по полям этого объекта. Объявление такого контейнера будет выглядеть примерно так:
// структура с кучей нужных полей
struct callback_t {
long system_id;
long server_id;
long callback_id;
// далее что-то ещё есть возможно
};

// определяем тип контейнера
typedef multi_index_container<
shared_ptr<callback_t>, // <<<<< хранится не объект, а указатель на него!
indexed_by<
ordered_unique<
composite_key< // <<<<< индексы объявляются, как если бы мы работали без обертки
callback_t,
member<callback_t, long, &callback_t::system_id>,
member<callback_t, long, &callback_t::server_id>
>
>
>
> callbacks_t;

А использование ничуть не сложнее, чем обычно:
void main() {
callbacks_t lot_of_callbacks;

callback_t* p = new callback_t; // тут конструктор обычно принимает параметры, но упрощено для примера

lot_of_callbacks.insert( shared_ptr<callback_t>( p ) );
// в lot_of_callbacks хранится не сам объект, а указатель на него

// но поиск работает как обычно
callbacks_t::const_iterator cb_iterator = lot_of_callbacks.find( boost::make_tuple( 1, 1 ) );
}

вторник, 7 октября 2008 г.

Ubuntu 8.10 coming soon

Уже некоторое время назад анонсирована новая версия Ubuntu. В моём блоге есть официальный счетчик дней до выхода.

Из всех нововведений самое важно, на мой взгляд, то, что наконец-то появится возможность управлять полноценно сетью через Network Manager. Ранее сеть не работала до логина, если её настраивать через этот самый Network Manager, поэтому приходилось точить конфиги. Теперь обещают, что будет работать...

Более подробно о новых фичах тут. Для любителей KDE тоже есть ссылка - тут можно посмотреть о новинках в Kubuntu.