Умный способ убрать грязный флаг в C ++ - PullRequest
0 голосов
/ 25 мая 2018

У меня есть случай, когда я пытаюсь представить стандартный API для структур пространственного поиска, где входные данные для различных методов построения структуры одинаковы, но способ построения структуры поиска отличается.У меня есть сеттеры для данных базового класса и чисто виртуальный метод Build (), который необходимо реализовать производным классам для построения структуры поиска.Ниже приведен пример того, как выглядит мой базовый класс

class SpatialSearch
{
public:
  void SetData(Data data_)
  {
    this->data = data_;
    this->dirty = true;
  }

  virtual void Build() = 0;

  int search(Vec3 point)
  { 
    if(dirty)
      Build();
    // Code to perform a search. I won't get into the 
    // nitty gritty of this, but this exists as a commom
    // implementation on the base class for all the spatial 
    // search structures.
  }

private : 
  Data data;
  bool dirty;
}

Так что, если вы заметили, каждый запрос на поиск имеет проверку на флаг dirty.И если данные были изменены после последнего раза, я перестраиваю структуру.Тем не менее, метод Build реализован в производном классе, и мне нужен способ применить средство установки этого флага на false после выполнения метода Build, а не просто оставить руководство для человека, пишущего производный классиметь dirty = false в их методе «Build».

Короче говоря, мне нужен способ убедиться, что пользователь установил dirty = false после каждого выполнения метода Build.

1 Ответ

0 голосов
/ 25 мая 2018

Обычный способ сделать это - иметь вертикальный интерфейс и горизонтальный (защищенный и общедоступный).

"Горизонтальный интерфейс" - это тот, который видят пользователи класса, и "вертикальный"один - тот, который реализаторы производного класса переопределяют, чтобы добавить функциональность.

class SpatialSearch
{
public:
  void SetData(Data data_)
  {
    this->data = data_;
    this->dirty = true;
  }

  void Build() // no longer virtual
  {
    internal_build(); 
    dirty = false;
  }

  int search(Vec3 point)
  { 
    if(dirty)
      internal_build();
    // Code to perform a search. I won't get into the 
    // nitty gritty of this, but this exists as a commom
    // implementation on the base class for all the spatial 
    // search structures.
  }

protected:
  virtual void internal_build() = 0; // implementers override this

private : 
  Data data;
  bool dirty;
}

class SpecialSpatialSearch
: public SpatialSearch
{
protected:
  void internal_build() override
  {
    // do the build without caring or knowing of the 
    // existence of the dirty flag
  }
};
...