ModelResetter RAII Object

У меня есть пользовательская модель прокси, которая иногда перестраивает себя, когда в исходную модель добавляется новый столбец / строка. Из документов видно, что QAbstractItemModel :: beginResetModel () а также QAbstractItemModel :: endResetModel () в начале и конце такой операции — правильная методология. К сожалению, моя функция капитального ремонта имеет несколько возможных точек выхода, и я просто знаю, что забуду позвонить endResetModel на каждой точке выхода, поскольку это становится все более сложным.

Поэтому я хотел бы создать простой класс RAII, который будет вызывать beginResetModel на строительстве, а затем позвоните endResetModel после уничтожения, как следует:

class ModelResetter
{
public:
ModelResetter(QAbstractItemModel* model) : m_model(model)
{
m_model->beginResetModel();
}
~ModelResetter()
{
m_model->endResetModel();
}

private:
QAbstractItemModel* m_model;
};

Проблема в том, что beginResetModel() а также endResetModel() оба protected в QAbstractItemModel, декларирование ModelResetter как friend class в моем унаследованный модель не помогает, так как я пытаюсь взаимодействовать с базовым классом.

Я бы предпочел не делать пользовательскую реализацию для каждой модели, которую я реализую, поэтому я могу сделать это с помощью шаблонов? Я еще не очень знаком с синтаксисом шаблона.

Изменить 1: (Я удалил образец кода шаблона в Edit 2, чтобы избежать путаницы)

Было бы хорошо, если бы я мог как-то ограничить шаблон, чтобы разрешить только типы, которые наследуют QAbstractItemModel, но я не вижу ничего в стандартном C ++, который позволил бы это. Я не буду использовать Boost.

Редактировать 2Думаю, я не совсем понимал свои требования. Вот они:

  • Работает на базовом классе для общего случая
  • Обеспечивает QAbstractItemModel Требование наследования в режиме отладки без штрафа в режиме выпуска
  • Простое использование практически без накладных расходов
  • Не требует модификации базового класса или новых функций

2

Решение

вы могли бы иметь ваши унаследованные модели, которые бы представляли методы, которые будут просто вызывать beginResetModel () и endResetModel () соответственно, а затем ModelResetter вызывать эти методы.

1

Другие решения

Ненавижу отвечать на свой вопрос, но через пару дней я собрал решение на основе шаблонов, которое отвечает всем моим требованиям. Yay для моего первого с нуля шаблона класса. Вот реализация:

//modelresetter.h
#include <QAbstractItemModel>

/* you must declare this class as a friend to your model
* to give it access to protected members as follows:
* template <class Model> friend class ModelResetter;
*/
template<class Model>
class ModelResetter
{
public:
ModelResetter(Model* model) : m_model(model)
{
Q_ASSERT_X(qobject_cast<QAbstractItemModel*>(model) != 0, __FUNCTION__,
"templated object does not inherit QAbstractItemModel");
m_model->beginResetModel();
}
~ModelResetter()
{
m_model->endResetModel();
}

private:
Model* m_model;
};

и использование:

//mymodel.cpp
bool MyModel::overhaul()
{
ModelResetter<MyModel> resetter(this); resetter;  //prevent compiler warning

//do stuff
if(somethingswrong)
return false; //model will finish reset at every exit point

//do more stuff
return true; //model also completes reset on success
}

Спасибо за вашу помощь!

0

По вопросам рекламы [email protected]