У меня есть пользовательская модель прокси, которая иногда перестраивает себя, когда в исходную модель добавляется новый столбец / строка. Из документов видно, что 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
Требование наследования в режиме отладки без штрафа в режиме выпускавы могли бы иметь ваши унаследованные модели, которые бы представляли методы, которые будут просто вызывать beginResetModel () и endResetModel () соответственно, а затем ModelResetter вызывать эти методы.
Ненавижу отвечать на свой вопрос, но через пару дней я собрал решение на основе шаблонов, которое отвечает всем моим требованиям. 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
}
Спасибо за вашу помощь!