Класс коллекции C ++ для вызова дочерних функций - PullRequest
1 голос
/ 22 сентября 2011

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

MyCollection<Student> BiologyStudents();
// [Fill the collection]
BiologyStudents.EnrollInClass(ClassList::Biology);
BiologyStudents.Commit();

Идея состоит в том, что я могу легко записать всех учащихся в класс, используя свою коллекцию, и затем зафиксировать эти изменения в базе данных.Моя проблема в том, как выставить ту функцию EnrollInClass(), которая принадлежит дочерним объектам Student?Если моя коллекция содержит объекты другого типа, чем Student, я бы хотел, чтобы эти функции были доступны из коллекции.Единственный способ, которым я могу подумать сделать это с моими полуограниченными знаниями C ++, - это создать функцию, которая принимает параметр, который ссылается на функцию, которую я знаю, в содержащем дочернем классе.Это не приведет к ошибкам компиляции, если вы вызовете неправильную функцию или предоставите неправильные параметры, поэтому я хотел бы использовать компилятор для этих проверок.

Возможно ли это?Если так, то как?В качестве предупреждения я привык к общему программированию на Java / C #, поэтому моё представление о шаблонах C ++ может быть немного неправильным.

1 Ответ

2 голосов
/ 22 сентября 2011

Один из способов - использовать указатель на метод:

template <typename T>
struct MyCollection {
  template <typename U>
  void ForEach(void (T::*func)(U),U param)
  {
    // for each item loop goes here
    (item.*func)(param);
  }
};


MyCollection<Student> BiologyStudents;
// [Fill the collection]
BiologyStudents.ForEach(&Student::EnrollInClass,ClassList::Biology);

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

С C ++ 11 вы можете сделать это:

template <typename T>
struct MyCollection {
  void ForEach(std::function<void (T &)> func)
  {
    // for each item loop goes here
    func(item);
  }
};


MyCollection<Student> BiologyStudents;
// [Fill the collection]
BiologyStudents.ForEach([](Student &s){s.EnrollInClass(ClassList::Biology);});

Что не потребует создания разных версий ForEach для разного количества параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...