Sep 13

Iterators must go by Andrei Alexandrescu. Всем C++-никам посвящается!

PS. Всех коллег поздравляю с Днем программиста.

written by fxposter \\ tags:

Jun 10

Нужен хороший C++-программист для интересного проекта (создание поискового движка для веб-сайта).

Требования:

  • Обязательны хорошие знания в следующих областях:
    • C++
    • Linux
    • Pthreads
    • Sockets
    • Алгоритмы (в частности графы)
  • Желательно знать:
    • Boost (Thread, Asio, Graph, etc)
    • Ruby/Rails
    • MySQL/PostgreSQL/BerkeleyDB
    • Паттерны проектирования

Работать нужно в офисе (как оказалось, для некоторых это критично). Офис находится в Днепропетровске, в центре города.

Ответы пишите сюда, в Skype (fxposter), Jabber (fxposter@gmail.com) или ICQ (625585).

PS. Для того, чтобы не появлялись вопросы типа “а причем тут рельсы?” - сам проект пишется на Ruby/Rails, часть поискового движка - на C++.

written by fxposter \\ tags:

Mar 22

Кто-нибудь может посоветовать хорошую библиотеку регулярных выражений для C++. Требования (желательно, но, в принципе, не обязательно):

  • скорость
  • отсутствие (или хотя бы минимум) зависимостей от другой библиотеки
  • работа с GCC или Visual Studio 2008 (вот это очень бы хотелось, но, думаю, фиг найду)

Погуглил - нашел кучу самых разных библиотечек. Выбирать наугад не хочется, так что прошу совета у C++’ников.

written by fxposter \\ tags:

Mar 07

… статья под названием “За что я не люблю С++“. Лично мне как человеку знающему язык C++ достаточно хорошо статья очень понравилась и я практически во всем согласен с её автором. C++ действительно очень сложный язык, который к тому же является очень негибким на этапе выполнения (да, да, скорость работы, я понимаю…), и имеющий просто потрясающе огромное количество мелких ловушек, при встрече с которыми можно стать в ступор на долгое время.

PS. Линк на статью нашел у Bolk’а.

PPS. А есть ли аналоги C++, кроме D? Я имею ввиду, которые бы компилировались в нативный код и были такими же эффективными (или хотя бы похожими по эффективности).

written by fxposter \\ tags:

Dec 22

Вообще крышу срывает эта учеба…

Делал лабу по C++. Имеем классы:

enum AttributeType {BOOL, INT, DOUBLE, STRING};
class Attribute;
class BoolAttribute;
class IntAttribute;
class DoubleAttribute;
class StringAttribute;

Зачем - не спрашивайте. Кривовато (из-за AttributeType), но на С++ по другому не получалось.

Неделю назад час ебался мучался вопросом, какого хера почему это у меня каст из BoolAttribute* в Attribute* делал хер знает непонятно что, но только не то, что нужно… В итоге забил… Сейчас сел доделывать лабу… На 2-й минуте меня осенило - забыл прописать наследование… Пипееец. Нужно было так:

enum AttributeType {BOOL, INT, DOUBLE, STRING};
class Attribute;
class BoolAttribute : public Attribute;
class IntAttribute : public Attribute;
class DoubleAttribute : public Attribute;
class StringAttribute : public Attribute;

Я с себя потихоньку шизею…

written by fxposter \\ tags:

Nov 01

Что-то я затянул немного выполнение лабораторных работ некоторых по универу, нужно исправляться. Сегодня решил вернуться ко второй лабе по ООП. Задание таково:

“Разработать объектно-ориентированную библиотеку для работы со структурами данных по одной из нижеперечисленных тем в соответствии с нижеуказанными требованиями. Свойства и методы для классов разработать в соответствии с известными определениями соответствующих структур данных. Составить тесты для проверки работоспособности библиотеки. Составить программу, демонстрирующую возможности разработанной библиотеки.”

Требования - хрен с ними, а вот тема мне попалась интересная: “Сетевые базы данных (ввод/вывод, навигация)”. Когда я это задание читал в первый раз - я впал в ступор. Потом оклемался, но когда видишь такое задание как-то не по себе становится…

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

Поговорил немного с преподами о задании, итог получился такой - “нам не нужна универсальная бд, сделай несколько таблиц статических и связывай их”. Говорил действительно немного - минуты полторы, так что кроме фразы выше я ничего особо не услышал. Сегодня решил хоть чего-нибудь напроектировать, чтобы в пятницу показать преподам и убедится, правильно ли я делаю, или нет. Мысля сейчас такая: есть отдельные таблицы (неважно, как представленные) и есть какой-нибудь класс Relation, который их связывает. Собственно, это очень напоминает обычную иерархическую бд (таблица - связующая таблица - таблица), но как это оформлять по другому я пока что не представляю.

Сел за комп, закодил… Получилось такая фигня:

class Masseur : public Record {
public:
    Masseur();
    virtual ~Masseur();
private:
    char* _name;
    char* _surname;
    char* _fathername;
    char* _qualification;
    Date _birthday;
};

class Service : public Record {
public:
    Service();
    virtual ~Service();
private:
    char* _name;
    char* _part;
    int _duration;
    double _price;
};

class MasseurServiceRelation : public Relation {
public:
    MasseurServiceRelation();
    virtual ~MasseurServiceRelation();
private:
    void add(Masseur*, Service*);
    void remove(Masseur*, Service*);
    void remove(Service* service);
    void remove(Masseur* masseur);
};

Сейчас сижу и думаю, правильным ли путем я иду…

PS. А первые две таблицы очень напоминают паттерн ActiveRecord, на правда ли? :)

written by fxposter \\ tags:

Oct 26

В свое время выбирал IDE для работы с C++, посоветовали попробовать Code::Blocks. Попробовал, понравилось. Симпатичная IDE, хороший автокомплит, неплохая настраиваемость, поддержка gcc - а мне другого и не нужно было. После того, как я заинтересовался Qt, я стал искать плагины для поддержки этой библиотеки к Code::Blocks. Нашел QtWorkbench. Вот только плагин к линукс-версии можно подключить, только заново скомпилировав саму программу. Чем я раньше и занимался - ведь вот есть хорошая инструкция. Вчера заметил странную директорию debian, которая находится в Code::Blocks’овом trunk’е. Там есть файлик rules, после его просмотра стало ясно, что здесь все уже сделано для построения пакетов для Debian-based дистрибутивов линукса. И вот решил я ночью пакет сделать, со встроенным QtWorkbench’ем.

Для конфигурирования и сборки пакетов:

sudo apt-get install libtool autoconf automake dh-make

Если у вас не Ubuntu/Gutsy - следуем этим инструкциям и добавляем в apt нужный репозиторий. Устанавливаем wxwidgets и g++:

sudo apt-get install g++ wx-common libwxgtk2.8-dev

Также мне в Kubuntu пришлось установить libgtk:

sudo apt-get install libgtk2.0-dev

Далее - следуем начальным инструкциям отсюда:

svn checkout svn://svn.berlios.de/codeblocks/trunk codeblocks
cd codeblocks/
wget http://qtworkbench.googlecode.com/files/QtWorkbench-src-0.5.1.tar.gz
tar zxf QtWorkbench-src-0.5.1.tar.gz
patch --unified --strip=0 --forward --input=qtworkbench.patch
./bootstrap

Конфигурируем для установки всех плагинов и указываем, что ставить нужно в /usr:

./configure --prefix=/usr --with-contrib-plugins=all

Теперь нужно указать, что мы хотим включить в пакеты и QtWorkbench (если этого не сделать - dh-make выдаст после линкования и компиляции всех файлов, что у вас есть лишние файлы и откажется создавать пакет):

sudo nano debian/codeblocks-contrib.install

И добавляем в конец файла эти строчки:

usr/share/codeblocks/QtWorkbench.zip*
usr/share/codeblocks/plugins/libQtWorkbench.*

Сохраняем файл и начинаем делать пакеты (у меня компилировалось и линковалось долго, больше получаса, так что будьте терпеливы):

sudo ./debian/rules binary-arch

На выходе получаем 7 пакетов и ставим Code::Blocks:

cd ..
sudo dpkg -i libcodeblocks0_1.0svn4561_i386.deb libwxsmithlib0_1.0svn4561_i386.deb codeblocks_1.0svn4561_i386.deb codeblocks-contrib_1.0svn4561_i386.deb

Я использовал svn4561-ревизию, так что у вас номер в deb-файлах скорее всего будет другой. Учитывайте это.

Собранные мной пакеты лежат здесь (ubuntu 7.10) и здесь (debian unstable).

written by fxposter \\ tags: , , , , ,

Oct 23

Начнем издалека… Есть в C++ встроенный тип size_t, который является “целым типом без знака, используемым реализацией для индексирования массивов” © Страуструп. То есть, если вы работаете с индексами в массивах и их длинами, то в общем-то “правильнее” использовать не int, что в большинстве случаев и делается, а именно size_t (для длин можно еще использовать ptrdiff_t - тип, который возвращает операция вычитания двух указателей). Вчера эта “правильность” для меня вышла боком…

size_t length;
...
for(size_t i = 0; i < length; ++i) {
    double x = 2 * (i - length / 2) / length;
    ...
}

Вот такой был изначальный код. Через несколько минут после написания я вспомнил, что неплохо бы сделать так:

size_t length;
...
for(size_t i = 0; i < length; ++i) {
    double x = 2 * static_cast<double>(i - length / 2) / length;
    ...
}

потому что при делении двух целых чисел у нас тоже целое будет, а мне нужно было как раз вещественное.

Но это еще ладно. После этого я отдал свой кусок лабораторной (мы ее пишем парами) своей девушке (а я как раз с ней пишу). Когда она добралась до этого кода и стала тестить его - у нее стали получаться какие-то странные, неправильные числа. Долгое время я копался в коде и не мог понять, в чем проблема, а потом до меня наконец-то дошло - разность двух беззнаковых чисел также будет беззнаковая (т.е. число -1 будет на самом деле 0xFFFFFFFF), после чего код превратился в такой:

size_t length;
...
for(size_t i = 0; i < length; ++i) {
    double x = 2 * static_cast<double>(static_cast<int>(i) - static_cast<int>(length) / 2) / length;
    ...
}

После чего я на всякий случай еще полчаса проверял небольшую программу на вот такие ошибки - на всякий случай. К счастью, таких больше не нашлось, но неприятный осадок остался.

Выводы: или пишите не особо заморачиваясь на правильности употребления типов (везде используйте int и double, например), или пишите семантически правильно, но не делайте таких ошибок, как я… Может, конечно, это только я такой, но мне лично сложно было именно по коду определить, что результат будет получаться не такой как я хочу.

PS. Я теперь немного понимаю, почему в Java нет unsigned типов. :) 

written by fxposter \\ tags:

Oct 06

Не могу не отметить статью из октябрьского номера MSDN Magazine про “Оптимизацию управляемого кода для многоядерных компьютеров”. В статье рассказывается о библиотеке TPL, которая позволяет использовать все преимущества многоядерности практически без изменений исходных кодов (по сравнению с переписыванием кода с использованием Thread’ов - здесь изменения в коде потребуются лишь чисто косметические).

На мой взгляд, готовится бомба, так как использование фич многоядерных процессоров становится до неприличия простым. Статья очень интересна как в теоретическом, так и в практическом плане. Так что советую ее почитать всем программистам, даже тем, кто с C# не знаком - ведь возможно, в ближайшем будущем именно такой подход и будет использоваться.

PS. В “более далеком” будущем, как мне кажется, эта библиотека перекочует в компилятор, который сам будет решать - нужно ли распараллеливать текущий код или нет.

PPS. Интересно, уйдут ли Thread’ы в небытие? :)

written by fxposter \\ tags: ,

Oct 03

Достаточно интересный факт - MS открывает исходники многих библиотек .NET фреймворка, в частности .NET Base Class Libraries (System, System.IO, System.Collections, System.Configuration, System.Threading, System.Net, System.Security, System.Runtime, System.Text, etc), ASP.NET (System.Web), Windows Forms (System.Windows.Forms), ADO.NET (System.Data), XML (System.Xml), and WPF (System.Windows). В дальнейшем планируется открытие и остальных библиотек.

В чем основные плюсы этого решения для .NET-программистов:

  • Изучение исходников фреймворка, учиться ведь всегда полезно :)
  • Возможность использования исходников при отладке своего приложения в VS 2008:

Теперь о подводных камнях - код открыт по лицензии Microsoft Reference License (MS-RL), которая подразумевает возможность только просмотра кода, перекомпиляция или изменение этих кодов по лицензии строго-настрого запрещены. То есть на развитие того же Mono Project это решение фирмы MS никак не повлияет, а жаль - очень бы хотелось, чтобы Mono был реальным аналогом того .NET’а, которым нас балует MS.

И вдогонку - на днях наткнулся на очень хорошую статью по нововведениям в C# 3.0, которая меня очень порадовала - в отличии от Java, C# не стоит на месте, а развивается. В Java в основном меняется библиотека стандартная, в случае же C# + .NET Framework меняются обе составляющие: язык становится более удобным (как по мне - гораздо более удобным, мне Linq ну просто очень понравился), а .NET Framework обрастает новыми функциями.

written by fxposter \\ tags: , , ,