Виталий Ткаченко - Обратные вызовы в C++

Здесь есть возможность читать онлайн «Виталий Ткаченко - Обратные вызовы в C++» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 2021, Издательство: Array SelfPub.ru, Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Обратные вызовы в C++: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Обратные вызовы в C++»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

В практике разработки ПО зачастую встает задача динамической модификации программного кода в зависимости от текущих или настраиваемых значений параметров. Для решения этой задачи широко используются обратные вызовы. В языке C++ обратные вызовы реализуются различными способами, и далеко не всегда очевидно, какой из них лучший для конкретной ситуации. В книге рассмотрены теоретические и практические аспекты организации обратных вызовов, проанализированы достоинства и недостатки различных реализаций, выработаны рекомендации по выбору в зависимости от требований к проектируемому ПО. В первую очередь книга предназначена для программистов среднего (middle) уровня, т.е. тех, кто уже достаточно хорошо знает язык C++, но хотел бы расширить и углубить свои знания в области проектирования и дизайна. В определенной степени она также будет интересна опытным разработчикам, с одной стороны, как систематизация знаний, с другой стороны, как источник идей и методов для решения практических задач.

Обратные вызовы в C++ — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Обратные вызовы в C++», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

auto lambda = [capture](int eventID) {/*this is a body of lambda*/};

lambda(10); //lambda call

Однако указанный способ не будет работать, когда требуется сохранить лямбда-выражение в классе. Мы не можем объявить переменную – член класса с типом auto, потому что это означало бы объявление переменной заранее не определенного типа, что не допускается.

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

Добавим в реализацию инициатора, описанного в Листинг 37 п. 4.4.1, два конструктора. Один конструктор будет с переменной – аргументом обратного вызова для инициализации члена класса. Другой конструктор будет без аргументов (конструктор по умолчанию), чтобы оставить возможность отложенной настройки (Листинг 41).

Листинг 41. Инициатор с дополнительными конструкторами

template

class Initiator

{

public:

Initiator() {}

Initiator(const CallbackArgument& argument) : callbackHandler(argument) {}

void setup(const CallbackArgument& argument)

{

callbackHandler = argument;

}

void run()

{

int eventID = 0;

//Some actions

callbackHandler(eventID);

}

private:

CallbackArgument callbackHandler;

};

Для любых типов аргументов обратного вызова, кроме лямбда-выражений, допускается использование обоих конструкторов. Для лямбда-выражений допускается использование только конструктора с аргументом, при попытке использования конструктора по умолчанию компилятор выдаст ошибку. Кроме того, в этом случае нельзя будет вызвать метод setup – также будет сгенерирована ошибка. Таким образом, использование инициатора с лямбда-выражением не предполагает динамической модификации: настройка происходит один раз в конструкторе при инстанциировании шаблона, и больше изменить ее нельзя 20 20 Указанная проблема решается при использовании универсального аргумента, о чем пойдет речь в следующей главе .

А какой тип аргумента нам указывать при инстанциировании шаблона, ведь тип лямбда-выражения является анонимным? Для этой цели мы будем использовать ключевое слово decltype, которое возвращает тип объявленной переменной (см. Листинг 42).

Листинг 42.Инстанциирование шаблона асинхронного обратного вызова для лямбда-выражения

int capture = 10;

auto lambda = [capture](int eventID) {/*this is a body of lambda*/};

Initiator callbackLambda1 (lambda); // Ok, initialization in constructor

Initiator callbackLambda = lambda; // Ok, implicit constructor call

Initiator callbackLambda2; //Error: attempting to reference a deleted function

callbackLambda.setup(lambda); //Error: ‘operator’ = attempting to reference a deleted function

callbackLambda.run();

4.4.3. Исполнитель

В Листинг 43 приведены примеры реализации исполнителя для различных типов аргументов. Объявления класса CallbackConverterпредставлены в Листинг 27 и Листинг 28 п. 4.2.2, инициатор используется из Листинг 41 п. 4.4.2.

Листинг 43. Исполнитель для шаблона-инициатора с различными типами аргумента

class Executor // (1)

{

public:

static void staticCallbackHandler(int eventID, Executor* executor) {}

void callbackHandler(int eventID) {}

void operator() (int eventID) {}

};

void ExternalHandler(int eventID, void* somePointer) {} // (2)

int main()

{

Executor executor; // (3)

int capturedValue = 0;

// (4) Pointer to the external function

using PtrExtFunc = void(*) (int, void*); // (5)

using CallbackExtFunction = CallbackConverter; // (6)

Initiator initExtFunction; // (7)

initExtFunction.setup(CallbackExtFunction(ExternalHandler, &executor)); // (8)

// (9) Pointer to the static method

using PtrStaticMethod = void(*) (int, Executor*); // (10)

using CallbacStaticMethod = CallbackConverter; // (11)

Initiator initStaticMethod; // (12)

initStaticMethod.setup(CallbacStaticMethod(Executor::staticCallbackHandler, &executor)); // (13)

// (14) Pointer to the class member method

using PtrMethod = void(Executor::*)(int); // (15)

using CallbackMemberMethod = CallbackConverter; // (16)

Initiator initMemberMethod; // (17)

initMemberMethod.setup(CallbackMemberMethod(&executor, &Executor::callbackHandler)); // (18)

// (19) Functional object

Initiator initFunctionObject; // (20)

initFunctionObject.setup(executor); // (21)

// (22) Lambda-expression

auto lambda = [capturedValue](int eventID) {/*Body of lambda*/}; // (23)

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Обратные вызовы в C++»

Представляем Вашему вниманию похожие книги на «Обратные вызовы в C++» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Обратные вызовы в C++»

Обсуждение, отзывы о книге «Обратные вызовы в C++» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x