if ( sensor->isOperable() && (number >= first_ && number <= last_) )  // (8)

    {

        (this->*arrayFunMinMax_[sign_])(sensor->getValue());              // (9)

        count_++;                                                         // (10)

    }

  }

  SensorValue result() { return result_; }  // (11)

  size_t count() { return count_; }         // (12)

private:

  SensorNumber first; // (13)

  SensorNumber last;  // (14)

  MinMaxSign sign;    // (15)

  SensorValue result; // (16)

  size_t count;       // (17)

  using FunMinMax = void (FindMinMaxValue::*)(SensorValue value);  // (18)

  void CompareMin(SensorValue value)  // (19)

  {

      if (result_ > value)

      {

          result_ = value;

      }

  }

  void CompareMax(SensorValue value)  // (20)

  {

    if (result_ < value)

    {

      result_ = value;

    }

  }

  FunMinMax arrayFunMinMax_[2];       // (21)

};

В строке 2 объявлен конструктор, который принимает на вход следующие параметры: минимальное значение диапазона номеров; максимальное значение диапазона номеров; параметр, указывающий, что необходим поиск минимального либо максимального значения. В конструкторе инициализируются переменные класса: минимальное значение диапазона (объявлено в строке 13); максимальное значение диапазона (объявлено в 14); параметр для поиска (объявлено в 15); итоговый результат (объявлено в 16); количество датчиков, которые участвовали в поиске (объявлено в 17). В зависимости от переданного параметра начальный результат инициализируется соответственно максимальным либо минимальным значением (строки 3 и 4). Кроме того, инициализируется массив указателей на функцию (строки 5 и 6, объявление в 21). Данные функции предназначены для сравнения и запоминания максимального либо минимального значений (объявлены в 19 и 20).

Анализ очередного значения происходит в перегруженном операторе 7. На вход подаются номер датчика и указатель на датчик. Если датчик работоспособный и его номер попадает в заданный диапазон номеров (строка 8), то в зависимости от параметра поиска через указатель вызывается соответствующая функция для анализа (строка 9), а также увеличивается счетчик просмотренных датчиков (строка 10). Функции 11 и 12 возвращают итоговые результаты.

Итак, класс для анализа готов. Теперь можно вызвать метод для итерации по элементам контейнера, и в качестве обратного вызова передать экземпляр соответствующего вспомогательного класса. Метод будет вызывать перегруженный оператор, и таким образом, мы узнаем минимальное либо максимальное значение (Листинг 101).

Листинг 101. Поиск минимального и максимального значений (SensorControl.cpp)

SensorValue SensorControl::getMinValue(SensorNumber first, SensorNumber last)

{

  checkInitialize();

  FindMinMaxValue fmv(first, last, FindMinMaxValue::MIN_VALUE);

  sensorContainer_->forEachSensor(fmv);

  return fmv.result();

}

SensorValue SensorControl::getMaxValue(SensorNumber first, SensorNumber last)

{

  checkInitialize();

  FindMinMaxValue fmv(first, last, FindMinMaxValue::MAX_VALUE);

  sensorContainer_->forEachSensor(fmv);

  return fmv.result();

}

<p>6.3. Разработка системного API</p><p>6.3.1. API как оболочка</p>

Уже после того, как классы модуля были разработаны, протестированы и начали использоваться в системе, появилось новое требование – ввести поддержку системного API. Как известно, в интерфейсах системных API можно использовать только внешние функции и простые структуры данных в стиле C; классы и другие специфические конструкции C++ использовать нельзя (см. п. 1.4.2). Так что же, все теперь придется переписывать? Можно предложить следующее решение: использовать интерфейс API как оболочку для вызова методов класса. Концептуальный пример приведен в Листинг 102.

Листинг 102. Концептуальный пример реализации API как оболочки
Перейти на страницу:

Похожие книги