Метка «c++» - 28

Calculator

Я хочу посвятить эту статью проблеме, о которой мало кто задумывается. Все шире и шире применяется моделирование различных процессов с помощью компьютера. Это замечательно, возможностью экономить время и материалы на бессмысленные химические, биологические, физические и прочие эксперименты. Обдув модели крыла на компьютере может в несколько раз сократить количество макетов, которое затем будет испытываться в реальной аэродинамической трубе. Численным экспериментам доверяют всё больше. Однако за торжеством численного моделирования никто не обращает внимания на рост сложности программ. В компьютере и к программам видят всего лишь инструмент для получения результата. Меня тревожит, что далеко не все знают и задумываются о том, что рост размера программы ведет к нелинейному росту числа ошибок. Опасно применять компьютер как просто большой калькулятор. Я и думаю, надо доносить эту мысль до других людей.
Читать полностью »

Доброго времени суток!

Задача

В текущем проекте столкнулся с необходимостью генерировать объекты-наследники от общего интерфейса, при этом порождать наследников необходимо, передавая им в конструкторе некий объект-инициализатор. Конструктора по-умолчанию у классов может и не быть. При этом конкретная фабрика объектов определяется в динамически подгружаемых плагинах, поэтому должна иметь определенный интерфейс.

Могу предложить два способа решения данной задачи.

Исходные данные

Допустим, интерфейс фабрик должен выглядеть следующим образом

class IFactoryBasic
{
public:
    IFactoryBasic() {}
    virtual ~IFactoryBasic() {}
    virtual Test* create(const QString &key, const QString &args)=0;
};

где Test — некий базовый класс

class Test
{
protected:
    QString _word;
public:
    Test(const QString &word):_word(word) {}
    virtual ~Test() {}
    virtual void test(){ qDebug()<<"test "<<_word; }
};

class TestChild: public Test
{
public:
    TestChild(const QString &word): Test(word) {}
    virtual void test() { qDebug()<<"test child"<<_word; }
};

TestChild — наследник Test
Оба класса принимают в конструкторе строковый параметр word, который потом мы можем верифицировать в функции test().

Первый способ

Способ простой. Он основан на создании шаблонного каркаса для будущей фабрики.

template<class T, class C, class A>
class IFactory
{
    QMap<QString, C* (T::*)(const A&) > handler;
protected:
    void add(const QString &key, C *(T::*func)(const A &))
    {
        handler[key]=func;
    }

public:
    IFactory() {}
    virtual ~IFactory() {}
    C *make(const QString &key, const A &args)
    {
        if(handler.contains(key))
        {
            T* inheritor = dynamic_cast<T*>(this);
            if(inheritor)
                return (inheritor->*handler[key])(args);
        }
        return 0;
    }
};

Здесь есть маленькое обязательство для пользователей класса. Первый шаблонный параметр должен быть классом, который наследуется от IFactory. Далее будут пояснения, для чего это было нужно.
handler в классе IFactory — ассоциативный контейнер, содержащий ключ и соответствующую функцию создания объекта. Сигнатура функции порождения описывается как C* (T::*)(const A&), то есть возвращаемое значение будет иметь указатель на некий класс C, как аргумент функции передается ссылка на объект типа A.
Функция add(...) добавляет в контейнер пару ключ-функция <key,func>.
Функция make(...) вызывает функцию порождения, если она имеется в контейнере (предварительно динамически преобразовав тип указателя this к типу наследника, иначе нельзя вызвать функции, которые там были определены).
Это основной каркас фабрики, осталось описать конкретную фабрику

class FactoryFst: public IFactory<FactoryFst, Test, QString>, public IFactoryBasic
{
    Test *createOrigin(const QString &args){ return new Test(args); }
    Test *createChild(const QString &args) { return new TestChild(args); }
public:
    FactoryFst()
    {
        add("test", &FactoryFst::createOrigin);
        add("testchild", &FactoryFst::createChild);
    }

    Test *create(const QString &key, const QString &args) { return make(key, args); }
};

Нетрудно догадаться, что мы используем множественное наследование для удовлетворения требованиям интерфейса IFactoryBasic. Для другого родителя мы явно указываем наследника FactoryFst, возвращаемый указатель будет указателем на объект класса Test, и в качестве аргумента передается ссылка на объект QString.
В соответствии с этим определением создаются функции, генерирующие объекты типа Test и TestChild:
Test *createOrigin(const QString &args){ return new Test(args); } — создает объект типа Test, передавая ему в конструктор аргумент QString.
Test *createChild(const QString &args) { return new TestChild(args); } — аналогично создает объект типа TestChild.
Остается только в конструкторе FactoryFst зарегистрировать данные функции и определить функцию create(...) интерфейса IFactoryBasic.

Второй способ

Этот метод в большей степени использует шаблоны.
Для построения фабрики нам нужна небольшая подготовка. Для начала нужно определить некоторые используемые фабрикой классы.

Для начала определим вспомогательный класс для хранения значений передаваемого аргумента. Для того, чтоб можно было беспрепятственно использовать указатели на данный класс, сделаем его наследуемым от нешаблонного базового класса.
Читать полностью »

Шаблон проектирования или паттерн — повторимая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках некоторого часто возникающего контекста.

Кажется, это определение мы слышали тысячу раз… Помимо знания терминов и паттернов интересно знать, как они применяются в реальных проектах.

В статье я рассмотрю несколько наиболее популярных паттернов используемых в .NET. Некоторые из них глубоко интегрированы в инфраструктуру .NET, в то время как другие просто применяются при проектировании базовых классов в BCL.

Паттернам проектирования посвящен не один десяток книг, но одна книга стоит особняком и это знаменитая книга «Банды четырех». Поэтому для большего понимания ситуации я буду приводить небольшое описание из этой книги.
Читать полностью »

Если бы языки программирования были детскими конструкторами

Всем привет! Как то случайно года 3 назад представил язык Pascal как детский конструктор, и написал об этом заметку. Показал друзьям, они заценили. Позже добавил C#, C++, HTML и Ассемблер. Надеюсь,ам понравится. Приятного чтения!
Читать полностью »

в 10:15, , рубрики: .net, tdd, метки: , ,

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

Сразу оговорюсь, что примеры приводятся применительно к языку C# и платформе .NET. Соответственно, в других языках/платформах подходы и реализации могут отличаться.

Итак…
Читать полностью »

Скоро первое сентября. Кто-то собирается в школу, кто-то — в институт. А мы предлагаем начать новые проекты с компилятором clang, который теперь поддерживает OpenMP!

Проект доступен здесь. Сейчас в его основе лежит clang 3.3. Небыстрый процесс ревью уже идет, и скоро код будет залит в транк clang'а, а значит войдет в его новые релизы.

Реализована полная поддержка стандарта OpenMP версии 3.1. Успешно проходятся следующие тесты: набор для валидации OpenMP от OpenUH Research Compiler, SPEC OMP2012 и внутренние тесты Intel. Исполняемый код c OpenMP, собранный clang'ом, демонстрирует производительность, сравнимую с другими компиляторами, поддерживающими OpenMP.
В качестве библиотеки времени выполнения использована библиотека Intel OpenMP Runtime Library, также доступная под свободной лицензией.
Читать полностью »

Как в сравнительно короткие сроки написать компилятор какого-либо языка программирования. Для этого следует воспользоваться средствами разработки, автоматизирующие процесс. Я хотел бы рассказать о том, как я писал компилятор языка программирования MiniJava под платформу .NET Framework.

Весь процесс написания компилятора в целом отображён на следующем изображении. На вход подаётся файл с исходным кодом на языке программирования MiniJava. Выходом является PE-файл для выполнения средой CLR.

Компилятор языка программирования MiniJava

Далее я хотел бы сконцентрироваться на практической части описания.
Читать полностью »

Shareaza — свободный файлообменный клиент и менеджер закачек для Windows с поддержкой протоколов Gnutella, Gnutella2, eDonkey2000, BitTorrent, DC++, FTP и HTTP. Умеет работать с magnet-, ED2K-, piolet- и Gnutella-ссылками, а также со стандартными HTTP- и FTP-ссылками. Переведён на 27 языков.

© Wikipedia

Итак я решил делать случайно-последовательную загрузку в клиенте Shareaza.

Посмотрел код на сайте. http://sourceforge.net/p/shareaza/code/9293/tree/trunk/shareaza/DownloadTransfer.cpp#l375 Судя по всему именно здесь и происходит вся магия. Но до модификаций нужно скомпилировать и установить Shareaza. Об этом и пост.
Читать полностью »

Использовать шаблонные шаблонные параметры С++ довольно сложно. Хочу продемонстрировать силу boost::mpl и показать трюк, позволяющий описывать шаблоны, полностью отказавшись от шаблонных шаблонных параметров.
Продемонстрирую проблему. Есть класс, принимающий тип объекта и тип контейнера для этого объекта.

template <typename T, typename Container>
struct A
{
  typedef Container<T> type;
};

Так писать нельзя, вы должны использовать шаблонные шаблонные параметры, чтобы указать, что Container сам по себе является шаблоном.
Читать полностью »

У меня с коллегами нередко возникают разговоры о быстродействии того или иного участка кода. Часто они перерастают в спор о том, какое же решение работает более быстро. И в этой ситуации чаще лучше набросать простенький бенчмарк, чем вести долгие философские разговоры о производительности. К сожалению, очень многие не умеют бенчмаркать правильно, в результате чего их тесты могут показать в корне неверные результаты. Поэтому мне хотелось бы обсудить наиболее важные вещи, которые нужно учитывать при составлении грамотного бенчмарка на C#.


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js