Главная страница
Навигация по странице:

  • Неуправляемые указатели

  • Вспомогательная библиотека marshal_as

  • Код на языке IL и неуправляемый код

  • Windows Forms в Visual Studio на C++ 15.4.1 Создание проекта CLR c Windows Forms

  • 15.4.2 Создание формы приложения CLR

  • Панель элементов

  • Свойство

  • Основные виды элементов управления

  • Событийное программирование

  • 16 Список источников

  • ООП. Пособие по ООП в С++. Создание сложных программных систем Объектно ориентированная технология


    Скачать 2.1 Mb.
    НазваниеСоздание сложных программных систем Объектно ориентированная технология
    Дата21.02.2022
    Размер2.1 Mb.
    Формат файлаpdf
    Имя файлаПособие по ООП в С++.pdf
    ТипАнализ
    #369034
    страница15 из 15
    1   ...   7   8   9   10   11   12   13   14   15

    Пример. В примере демонстрируется:
    • описание структуры типа BOOK ссылочного типа, который содержит информацию о книге;


    • использование ключевого слова ref для указания того, что структура есть ссылочного типа;
    • использование утилиты gcnew для выделения памяти под структуру;
    • демонстрация использования управляемых указателей для оперирования объектами.
    Пусть за пределами описания класса описывается следующая структура: ref struct BOOK // ref - обозначает, что структура есть ссылочного типа
    {
    System::String Title;
    // заголовок книги
    System::String Author;
    // фамилия автора книги int year;
    // год издания float price;
    // стоимость книги
    };
    Тогда в методах этого класса можно использовать структуру
    BOOK
    приблизительно следующим образом:
    BOOK ^B; // переменная B есть типа "управляемый указатель"
    B = gcnew BOOK; // выделение памяти под структуру
    // заполнение полей структуры
    B->Title = "Title of Book";
    B->Author = "Author of Book";
    B->year = 1998;
    B->price = 399.85f;
    Что такое неуправляемые указатели (unmanaged pointers) и неуправляемые указатели на функции (unmanaged function pointers)?
    Неуправляемые указатели
    (unmanaged pointer
    ) – это традиционные указатели C/C++. Они являются указателями на объекты в неуправляемом объеме памяти, которая выделяется для выполнения программы.
    Неуправляемые указатели не являются совместимыми со спецификацией CLR.
    Неуправляемые указатели на функции – это указатели на функции, которые можно обрабатывать таким же образом, как и неуправляемые указатели на объекты (данные).
    Общая форма объявления указателя:
    тип_переменной * имя_указателя;
    где
    тип_переменной – это тип той переменной, на которую указывает указатель. Его еще называют базовый тип указателя;
    имя_указателя – имя переменной-указателя.
    Пример. Описание указателей, которые указывают на разные типы переменных. int * pi; // указатель с именем pi на тип int float * pf; // указатель с именем pf на тип float
    Пример операции взятия адреса и использование указателя для доступа к переменной. int * pi; // указатель с именем pi на тип int
    float * pf; // указатель с именем pf на тип float float f; int i; i = 8; pi = &i; // pi указывает на i
    *pi = 10; // i = 10 f = 2.93f; pf = &f; // pf указывает на f
    *pf = 8.85f; // f = 8.85 15.2
    Вспомогательная библиотека marshal_as
    В этом разделе мы остановимся на вспомогательной библиотеке marshal_as, входящей в состав версии Visual C++ 2017 и выше. marshal_as - это библиотека шаблонов, упрощающая реализацию маршалиига управляемых типов в неуправляемые и обратно.
    Она способна преобразовывать многие неуправляемые строковые типы, такие как char*, wchar_t*, std::string, std::wstring, CStringT,
    CStringT, BSTR, bstr_t и CComBSTR, в управляемые типы и обратно.
    Она способна автоматически выполнять преобразование символов Юникода и
    ANSI, а также выделять и освобождать память.
    Библиотека объявлена и реализована в файлах marshal.h (базовые типы), marshal_windows.h (типы Windows), marshal_cppstd.h (типы данных STL) и marshal_atl.h (типы данных ATL).
    Имеется возможность расширять библиотеку marshal_as реализацией преобразований пользовательских типов. Это помогает избежать дублирования кода, когда требуется организовать маршалинг одного и того же типа во многих местах в программе, и дает возможность обеспечить единообразие синтаксиса маршалинга разных типов.
    В следующем фрагменте демонстрируется пример расширения библиотеки marshal_as поддержкой преобразования управляемого массива строк в эквивалентный неуправляемый массив строк: namespace msclr { namespace interop { template<> ref class context_node^>
    : public context_node_base
    {
    private: const wchar_t** _tasks; marshal_context _context; public: context_node(const wchar_t**& toObject, array^ fromObject)
    {
    // здесь начинается логика преобразования
    _tasks = NULL; const wchar_t **pTasks = new const wchar_t*[fromObject->Length]; for (int i = 0; i < fromObject->Length; i++)
    {
    String ^t = fromObject[i]; pTasks[i] = _context.marshal_as(t);
    } toObject = _tasks = pTasks;
    }
    context_node() { this->!context_node();
    } protected:
    !context_node()
    {
    // При удалении контекста будет освобождена память,
    // выделенная для строк (и принадлежащая marshal_context),
    // поэтому массив - единственная память,
    // которую требуется освободить if (_tasks != nullptr) { delete[] _tasks;
    _tasks = nullptr;
    }
    }
    };
    }
    }
    // Теперь можно переписать метод Employee::DoWork: void DoWork(array^ tasks)
    {
    // Вся неуправляемая память освобождается автоматически,
    // как только marshal_context выйдет из области видимости msclr::interop::marshal_context ctx;
    _employee->DoWork(ctx.marshal_as(tasks), tasks-
    >Length);
    }
    15.3
    Код на языке IL и неуправляемый код
    Неуправляемый класс по умолчанию будет скомпилирован расширением C++/CLI в код на языке IL, а не в машинный код. Это может ухудшать производительность в сравнении с оптимизированным машинным кодом, потому что компилятор Visual C++ способен оптимизировать код лучше, чем JIT-компилятор.

    Чтобы повлиять на процедуру компиляции можно, добавив объявление
    #pragma unmanaged или #pragma managed перед требуемым разделом кода.
    Кроме того, в проектах VC++ имеется возможность включать поддержку
    C++/CLI для отдельных единиц компиляции (файлов .cpp).
    15.4
    Windows Forms в Visual Studio на C++
    15.4.1 Создание проекта CLR c Windows Forms

    Запустить Visual Studio.

    Файл > Создать > Проект

    Выбрать тип проекта CLR в подраздел VS C++ и выбрать пункт Пустой проект CLR.

    Когда проект будет создан, в обозревателе решений кликаем правой кнопкой мыши по созданному проекту. В открывшемся контекстном меню последовательно выбираем
    Добавить>Создать элемент и в открывшемся меню в разделе UI выбираем Форма
    Windows Forms.
    Когда форма будет добавлена, в обозревателе решений выбираем файл
    MyForm.cpp. Перед вами откроется новая вкладка с единственной строчкой кода:
    #include "MyForm.h"
    В этот файл нам необходимо добавить следующий код: using namespace System; using namespace System::Windows::Forms;
    [STAThreadAttribute] void Main(array^ args) {
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false);
    Project1::MyForm form;//имя вашего проекта
    Application::Run(%form);
    }

    После этого в свойствах проекта.
    • Выбираем подраздел Система в разделе Компоновщик и в строке Подсистема в правой части окна, выбираем Windows (/SUBSYSTEM:WINDOWS) и нажимаем
    Применить.

    Не закрывая окно свойств проекта, переходим в подраздел Дополнительно и в строке
    Точка входа пишем Main и после этого нажимаем клавишу ОК.

    На этом настройки проекта заканчиваются. Для редактирования внешнего вида формы, необходимо перейти во вкладку MyForm.h [Конструктор], кликнув дважды по файлу MyForm.h в обозревателе решений.
    Примечание. В последних версиях система создает проект и реализует перечисленные действия.

    15.4.2 Создание формы приложения CLR
    Windows Forms предоставляет широкий спектр элементов, которые условно можно разделить на два типа: интерфейсные – те которые видны пользователю и с которыми он может работать непосредственно (разного рода кнопки, панели, таблицы) и служебные – те, что выполняют определенные задачи и вызываются путем взаимодействия пользователя с интерфейсными элементами (диалоги, таймеры, адаптеры).
    Перед использованием элемент должен быть помещен на форму
    (обычно при помощи drag&drop или как его называют «перетаскивание»), за исключением самого элемента формы (элемент форма создается автоматически при создании проекта см. раздел 1).
    Панель элементов
    Все элементы Windows Forms находятся на панели Toolbox (рисунок
    2.1).
    Рисунок 2.1 – Панель элементов (Toolbox)
    Каждый элемент содержит свой набор свойств и событий. Большинство из них повторяются для всех элементов (являются универсальными).
    Свойство в объектно-ориентированном программировании - способ доступа к внутреннему состоянию объекта, имитирующий переменную некоторого типа.

    Событие в объектно-ориентированном программировании — это сообщение, которое возникает в различных точках исполняемого кода при выполнении определённых условий.
    События предназначены для того, чтобы иметь возможность предусмотреть реакцию программного обеспечения.
    Все свойства элемента находятся на панели Properties и меняются вручную или выбираются из списка (рисунок 2.2), а события на панели Properties, вкладка Events
    (рисунок 2.3).
    Рисунок 2.2 – Свойства элемента Form
    Рисунок 2.3 – События элемента Form
    Основные виды элементов управления

    Пример формы Арифметический калькулятор
    Обработчик события Click от кнопки + с суммированием в выбранной системе счисления private
    : System::Void button1_Click(System::Object^ sender,
    System::EventArgs^ e) { calc.set_a(Convert::ToInt32(textBox1->Text)); calc.set_b(Convert::ToInt32(textBox2->Text)); int c=calc.sum(); if
    (ss()==2) textBox3->Text=StdToSys(convert2(c)); else if
    (ss()==16) textBox3->Text=StdToSys(convert16(c)); else textBox3->Text=Convert::ToString(c);
    }
    Где std::string convert2(
    int x)
    { string s=
    ""
    ,s1=
    ""
    ;
    int a; while
    (x)
    { a=x%2; s=(
    char
    )(48+a)+s; x=x/2;
    } return s;
    } std::string convert16(
    int x) std::string s=
    ""
    ; int y; while
    (x)
    { y=x%16; if
    (y>9)
    { s=(
    char
    )(
    int
    (
    'A'
    )+y%10)+s;
    } else
    { s=(
    char
    )(48+x%16)+s;
    } x=x/16;
    } return s;
    }
    15.5
    Событийное программирование
    Событи́йно-ориенти́рованное программи́рование СОП) — парадигма программирования, в которой выполнение программы определяется событиями — действиями пользователя (клавиатура, мышь), сообщениями других программ и потоков, событиями операционной системы (например, поступлением сетевого пакета).
    СОП можно также определить как способ построения компьютерной программы, при котором в коде (как правило, в головной функции программы) явным образом выделяется главный цикл приложения, тело которого состоит из двух частей: выборки события и обработки события.
    Как правило, в реальных задачах оказывается недопустимым длительное выполнение обработчика события, поскольку при этом программа не может реагировать на другие события. В связи с этим при написании событийно- ориентированных программ часто применяют автоматное программирование.
    Событийно-ориентированное программирование, как правило, применяется в трёх случаях:
    1. при построении пользовательских интерфейсов (в том числе графических);
    2. при создании серверных приложений в случае, если по тем или иным причинам нежелательно порождение обслуживающих процессов;

    3. при программировании игр, в которых осуществляется управление множеством объектов.
    В современных языках программирования события и обработчики событий являются центральным звеном реализации графического интерфейса пользователя. Рассмотрим, к примеру, взаимодействие программы с событиями от мыши. Нажатие правой клавиши мыши вызывает системное прерывание, запускающее определённую процедуру внутри операционной системы. В этой процедуре происходит поиск окна, находящегося под курсором мыши. Если окно найдено, то данное событие посылается в очередь обработки сообщений этого окна. Далее, в зависимости от типа окна, могут генерироваться дополнительные события. Например, если окно является кнопкой (в Windows все графические элементы являются окнами), то дополнительно генерируется событие нажатия на кнопку. Отличие последнего события в том, что оно более абстрактно, а именно, не содержит координат курсора, а говорит просто о том, что было произведено нажатие на данную кнопку.
    Обработчик события может выглядеть следующим образом (на примере
    C++/CLI): private void button1_Click(object sender, EventArgs e)
    {
    MessageBox.Show("Была нажата кнопка");
    }
    Здесь обработчик события представляет собой процедуру, в которую передается параметр sender, как правило, содержащий указатель на источник события. Это позволяет использовать одну и ту же процедуру для обработки событий от нескольких кнопок, различая их по этому параметру.
    16 Список источников
    Rational Rose 2000 и UML Визуальное моделирование - Терри
    Кватрани.htm https://docs.microsoft.com/ru-ru/cpp/dot
    -net/how-to-define-and-consume- classes-and-structs-cpp-cli?view=vs-2019 ---- C++/CLI https://ru.wikipedia.org/wiki/ Событийно - ориентированное программирование
    1   ...   7   8   9   10   11   12   13   14   15


    написать администратору сайта