Программирование на C++

10 способов прострелить себе ногу

Создание веб приложений

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

Подпись для третьего не придумал

Американец изнасиловал лошадь, потому что думал, что у них родится кентавр

Помощь обездоленным якутам на дальнем севере

Благотворительность (на правах рекламы)

пятница, 1 марта 2013 г.

Сигналы и слоты в Qt

Сигналы и слоты в Qt - это механизм, который используются для взаимодействия между несколькими объектами. Фактически, сигналы и слоты помогают нам реализовать шаблон "Наблюдатель" (скоро описание этого шаблона будет добавлено в блог, если в скором времени не появится, пинайте меня, в C# это интерфейс System.IObserver<T>, в бусте boost.signals). Эта особенность существенно различает Qt от других библиотек.

Основная идея слотов и сигналов:
Когда событие происходит, то вырабатывается сигнал, который посылается на слот, слот это обработчик сигналов, фактически, это обычный метод класса (их даже можно делать виртуальными), который определяется после идентификатора public slots.
Предположим, что у нас есть класс MyClass:
(Не забываем, что для использования этого механизма нужен специальный макрос Q_OBJECT, который должен быть определен в теле класса, к тому же только классы наследуемые от QObject могут содержать слоты и сигналы, поэтому сделаем наследование
/////////////////////////////////////////////////////
class MyClass : public QObject {
    Q_OBJECT
//Определение
}
////////////////////////////////
Начнем с сигналов:
Как было сказано это тоже обычные методы:
////////////////////////////////////////////////////
class MyClass: public QObject {
Q_OBJECT
public:
...
signals:
   void mySignal();
};
///////////////////////////////
Для выработки сигнала используем ключевое слово emit:
/////////////////////////////////////////////////////////////////////////////////
void MyClass ::sendMySignal()
{
   emit mySignal();
}
/////////////////////////////////////////////////
Хочу сказать, что сигналы автоматически определяются и их НЕ НАДО определять, просто оставляем объявление.
Теперь слоты:
Как видим слоты - это обычные методы, у них есть определение, в отличие от сигналов, все они размещаются после ключевого слова - slots,причем мы указываем для них уровень доступа. Также можно добавлять аргументы (этот пример без аргумента)
/////////////////////////////////////////////////////////////////////////////////////////////
class MyClass: public QObject {
Q_OBJECT
 
public slots:
   void mySlot()
   {
      ...
   }
};
///////////////////////////////////////////////////////
Соединение сигнала и слота:
Для соединения сигнала и слота мы используем метод connect(sender, SIGNAL(signal), receiver, SLOT(slot))
Для нашего примера (т.е. сигнал и слот выше имена):
connect(sender, SIGNAL(MySignal()), receiver, SLOT(MySlot()));
Благодаря этому, при возникновении сигнала MySignal() автоматически вызовется метод MySlot(), который обработает сигнал MySignal().

вторник, 26 февраля 2013 г.

Шаблон проектирования Абстрактная фабрика (Abstract factory) Реализация C#

Абстрактная фабрика - порождающий шаблон проектирования, используемый для создания ГРУППЫ объектов, реализующих одно поведение, то есть объекты одного типа, причем не специфируя их конкретные классы.

Абстрактная фабрика используется, когда:
  1. Система должна работать с группами объектов и объекты в этом семействе должны использоваться совместно.
  2. Система не должна зависеть от того, как создаются компоненты и взаимодействуют.
  3. Когда надо, чтобы при изменении класса конкретного продукта, не приходилось изменять класс клиента (класс, взаимодействующий  с созданными продуктами)
Действующие лица:
  • AbstractProduct — абстрактный продукт
    • определяет интерфейс для создания объектов, создаваемых методом CreateProduct, то есть он содержит виртуальные функции CreateProduct, где уже в ConcreteFactory переопределяются (override).
  • ConcreteProduct — конкретный продукт
    • реализует интерфейс Product (то есть у нас есть класс AbstractProduct, от которого у нас несколько производных классов, типа ConcreteProductA, либо ConcreteProductB и так далее)
  • AbstractProduct — абстрактный создатель
    • предназначен, для реализации интерфейса от производных классов типа ConcreteProduct
  • ConcreteFactory — конкретная фабрика
    • переопределяет фабричный метод таким образом, чтобы он создавал и возвращал объект класса ConcreteProduct.
  • Client - клиент
    • дает команды на получение продукта определенного семейства, к тому же в параметры передается фабрика, к-ая создает все объекты, фактически это наш интерфейс взаимодействия, с помощью которого, мы решаем какие объекты создать.

Диаграмма:
Шаблон:


//сам интерфейс абстрактной фабрики
//два абстрактных методов, к-ые переопределяются в наследниках
    abstract class AbstractFactory
    {
        public abstract AbstractProductA CreateProductA();
        public abstract AbstractProductB CreateProductB();
    }

    // "ConcreteFactory1" 
    class ConcreteFactory1 : AbstractFactory
    {
//переопредление методов интерфейсных для 1ой фабрики
        public override AbstractProductA CreateProductA()
        {
            return new ProductA1();
        }
        public override AbstractProductB CreateProductB()
        {
            return new ProductB1();
        }
    }

    // "ConcreteFactory2" 
    class ConcreteFactory2 : AbstractFactory
    {
//переопредление методов интерфейсных для 2ой фабрики
        public override AbstractProductA CreateProductA()
        {
            return new ProductA2();
        }
        public override AbstractProductB CreateProductB()
        {
            return new ProductB2();
        }
    }
//пошли уже наши интерфейсы продуктов
    // "AbstractProductA" 
    abstract class AbstractProductA
    {
    }

    // "AbstractProductB" 
    abstract class AbstractProductB
    {
//метод, который показывает, как продукт B взаимодействует с объектом А
        public abstract void Interact(AbstractProductA a);
    }
//реализация продуктов
    // "ProductA1" 
    class ProductA1 : AbstractProductA
    {
    }

    // "ProductB1" 
    class ProductB1 : AbstractProductB
    {
//определение
        public override void Interact(AbstractProductA a)
        {
            Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name);
        }
    }

    // "ProductA2" 
    class ProductA2 : AbstractProductA
    {
    }

    // "ProductB2" 
    class ProductB2 : AbstractProductB
    {
        public override void Interact(AbstractProductA a)
        {
            Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name);
        }
    }
//интерфейс взаимодействия, с помощью которого мы решаем какого типа создать объекты
    // "Client" - the interaction environment of the products 
    class Client
    {
        private AbstractProductA abstractProductA;
        private AbstractProductB abstractProductB;

        // Constructor, создается группа объектов, причем все в зависимости от типа фабрики
        public Client(AbstractFactory factory)
        {
            abstractProductB = factory.CreateProductB();
            abstractProductA = factory.CreateProductA();
        }
//запуск клиента
        public void Run()
        {
            abstractProductB.Interact(abstractProductA);
        }
    }

Main():

        static void Main(string[] args)
        {
            // Abstract factory #1 
            AbstractFactory factory1 = new ConcreteFactory1();
            Client c1 = new Client(factory1);
            c1.Run();

            // Abstract factory #2 
            AbstractFactory factory2 = new ConcreteFactory2();
            Client c2 = new Client(factory2);
            c2.Run();

            // Wait for user input 
            Console.Read();

        }
Вывод: Итак, все как в фабричном методе, только мы создаем ГРУППЫ объектов, и также у нас клиент занимается созданием объектов и анализ взаимодействия созданных объектов.

Шаблон проектирования Фабричный метод (Factory Method) Реализация C#

Фабричный метод используется для создания одного! объекта с определенным интерфейсом (типом).

Фабричный метод относится к порождающим шаблонам проектирования. Порождающие шаблоны проектирования используются для создания объектов, причем они позволяют быть независимыми от типа создаваемого объекта и от процесса создания.

Фабричный метод используется, когда:
  1. Заранее известно, когда создавать объект, но не известен его тип.
  2. Созданные фабричным методом объекты должны определятся уже в подклассе.
  3. Класс делегирует свои методы производному классу, после чего происходит определение, какой класс принимает какие методы.
Диаграмма:

Действующие лица:
  • Product — продукт
    • определяет интерфейс объектов, создаваемых абстрактным методом;
  • ConcreteProduct — конкретный продукт
    • реализует интерфейс Product (то есть у нас есть интерфейс IProduct, от которого у нас несколько производных классов, типа ConcreteProductA, либо ConcreteProductB и так далее)
  • Creator — создатель
    • предназначен, для реализации интерфейса от производных классов типа ConcreteCreator
    • содержит фабричный метод для создания объекта типа Product, который переопределяется в классах ConcreteCreatorA, ConcreteCreatorB;
  • ConcreteCreator — конкретный создатель
    • переопределяет фабричный метод таким образом, чтобы он создавал и возвращал объект класса ConcreteProduct.
На основе класса Factory создается один или несколько классов фабрик (причем эти фабрики имеют тип), и эти фабрики создают конкретные модели.

Шаблон:
//абстрактный класс создателя, который имеет абстрактный метод FactoryMethod, принимающий тип продукта
public abstract class Creator
{
    public abstract Product FactoryMethod(int type);
}
 
 
public class ConcreteCreator : Creator
{
    public override Product FactoryMethod(int type)
    {
        switch (type)
        {
            //возвращает объект A, если type==1
            case 1: return new ConcreteProductA();
            //возвращает объект B, если type==2 
            case 2: return new ConcreteProductB(); 
            default: throw new ArgumentException("Invalid type.", "type");
        }
    }
}

public abstract class Product { } //абстрактный класс продукт
 //конкретные продукты с разной реализацией
public class ConcreteProductA : Product { } 
 
public class ConcreteProductB : Product { }
 //
Потом в Main()

static void Main()
{       //создаем создателя
        Creator creator = new ConcreteCreator();
 for (int i = 1; i <= 2; i++)
 {
            //создаем сначала продукт с типом 1, потом с типом 2
     var product = creator.FactoryMethod(i);
     Console.WriteLine("Where id = {0}, Created {1} ", i, product.GetType());
 }
}
Здесь сначала создается сам конкретный создатель, который потом будет использоваться в создании продуктов, сначала ConcreteProductA, вывод на экран типа, потом ConcreteProductB, и также вывод его типа.

Итак, подводим итоги:

Самый главный недостаток, это необходимость создания объекта Creator для того, чтобы создать любой продукт с помощью метода FactoryMethod().

среда, 20 февраля 2013 г.

Установка библиотек Qt (кьют) для VS2010 и VS2012


Сегодня я расскажу как установить библиотеку 4.8.4. версии (и 5.0) под Visual Studio 2010 и VS2012. Хочу сказать, что вышла библиотека под версией 5 и ее установка аналогична для версии 4.8.4.
Итак, что на требуется, это:

  1. Visual Studio 2010 или 2012 msdn можно скачать на рутрекере или Dreamspark
  2. Qt 4.8.4 или 5.0 : 4.8.4 и 5.0
  3. Qt Add-In : qt Add-In для 4   qt Add-In для 5
Когда скачиваем Qt 4.8.4 (5.0) мы можем выбрать либо Windows (VS2010) или скачать .zip. .zip скачиваем только в том случае, если вы хотите сконфигурировать библиотеку под свои нужды.   Мы выберем легкий путь и установим через Qt Add-In. Если мы устанавливаем для VS2012, То также скачиваем Windows VS2010, но только другой qt Add-In для 5 ой версии!!
Если мы выбрали вариант Qt .zip то, при установке путь не меняем, пусть будет C:\Qt\  Так будет проще.
Далее устанавливаем Qt Add-In. Все, готово. Запускаем Visual-Studio 2010 и можно увидеть, что сверху появилась вкладка Qt.

пятница, 25 января 2013 г.

Перегрузка оператора вызова функций operator () в С++


Оператор вызова функций должен быть перегружен только как нестатический член класса!
Формат: 
тип operator () (список_параметров), где список параметров может быть неопределенным и значения могут быть определены по умолчанию.

Оператор вызова функций применяется в том случае, когда нужно использовать объект как функцию, в этом случае такие объекты называются объектами-функциями или функторами (functors). Рассмотрим пример на классе Point (точка):

class Point{
private:
 int x;
 int y;
public:
 Point(int x, int y){
  this->x=x;
  this->y=y;
 }
 Point() {}
 Point operator()(int i,int j){
  x=i;
  y=j;
  return *this;
 }
 Point operator+(Point obj){
  Point temp;
  temp.x = obj.x + x;
  temp.y = obj.y + y;
  return temp;
 }
 void show(){
  cout< < "x: "< < x< < " y: "< < y< < endl;
 }
};

int _tmain(int argc, _TCHAR* argv[])
{
 Point obj1(10, 20), obj2(1, 1); //вызываются конструкторы формата Point(x,y)

 obj1.show();
 obj1(7, 8); // вызывается оператор() который меняет наши значения.
 obj1.show();

 obj1 = obj2 + obj1(10, 10); // может быть использовано в выражениях
 obj1.show();

 getchar();
 return 0;
}
Результаты:
10,20
7,8
11,11

В другом случае нам пришлось бы писать функцию, где нужно было бы указывать значения. Один минус этого примера в том, что можно спутать оператор () с конструктором... 
Зато благодаря этой перегрузки можно написать такой код:

list  lst;
//инициализируем весь список
for_each(lst.begin(),lst.end(), Point(1,1));
///теперь все значения точек в списке поменяются на 1,1
///отличный способ использования stl

Также перегрузка этого оператора применяется в задаче индексирования многомерного массива и в задаче выделения подстроки.

Объект функция имеет такими преимуществами перед обычными функциями:

  • Каждому объекту функции соответствует свой тип.
  • Объект функции можно инициализировать на стадии выполнения перед ее вызовом.


понедельник, 21 января 2013 г.

Обфускация С# кода средствами VS2010

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

Dotfuscator Software Services, который встроен в VS2010.

Допустим, у нас есть какой то проект, возьмем мой - FormulaToTruthTable. Для того, чтобы начать, зайдем в Tools->Dotfuscator Software Services. 

Вылезет окошко с лицензией. Тщательно читаем еврейским методом и принимаем лицензию. После нескольких минут раздумываний появится окошко дотфускатора:
Программа содержит:
  • Дерево навигации (слева от синего окошка)
  • Рабочее поле (синее окошко)
  • И Build Output (там появляется информация во время построения кода)
Теперь правой клавишей по Dotfuscator1->Add Assemblies. Добавляем все .exe .dll файлы из проекта. В моем случае у меня 2 файла (выберите Input Assemblies в дереве для просмотра):
Далее выберем нужные нам свойства:
  • Honor instrumentation attributes - выбрав галочку, дотфускатор трансформирует все функциональные аттрибуты (к-ые влияют на юзабильность, функциональность программы). Они описаны здесь : msdn
  • Honor obfuscation attributes - для того, чтобы производилось обфусцирование с помощью специальных аттрибутов.
  • Library mode - говорит дотфускатору, что входная сборка является библиотекой.
  • Strip obfuscation attributes - (Strip - снимать (engl)) - снимает аттрибуты запутывания, т.е. не будут видны аттрибты обфусцирования, таким образом над методами не будут красоваться: [Obfuscation(Feature = "trigger", ApplyToMembers = true, Exclude = false)]
Я выбрал вот так:
Вообще дальше лучше ничего не менять, а то напортачите :D, так что сразу нажимайте Build->Build Project. После некоторого времени, В блоге появится вот такая статистика:
Build Finished.
Build Statistics    Total  Renamed  Percent Renamed
Types:                 10        6           60,00%
Methods:               67       58           86,57%
Fields:                34       33           97,06%
Это означает, что построение завершено. В папке Папка вашего проекта\obj\x86\Debug\Dotfuscated появится exe и все ваши dll файлы. Все ваши файлы обфусцированы и при запуске .exe все должно работать.
Результат в папке:

воскресенье, 20 января 2013 г.

Квайн (Quine) - С++

Квайн - это программа, которая печатает свой собственный код.
пример квайна:

Увы, один из вариантов является читом:
ifstream openfile("./Quine.cpp", ios::in);
 string temp;
 while ( getline(openfile, temp) )
 {
  cout < < temp < < endl;
 }
 openfile.close();
Так,как программа может и не знать, где находится файл с программой.
#include
char*i="\\#include ",n='\n',q='"',*p=
"%s%cchar*i=%c%c%s%c,n='%cn',q='%c',*p=%c%c%s%c,*m=%c%c%s%c%c;%s%c",*m=
"int main(){return!printf(p,i+1,n,q,*i,i,q,*i,q,n,q,p,q,n,q,m,q,n,m,n);}"
;int main(){return!printf(p,i+1,n,q,*i,i,q,*i,q,n,q,p,q,n,q,m,q,n,m,n);}
Пример с википедии, (partial quine)
Задача: написать максимально короткий квайн :3