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()都是QAbstractItemModel中的protected。在我的继承的模型中声明ModelResetterfriend class似乎没有帮助,因为我试图与基类交互。

我宁愿不为我实现的每个模型做一个自定义实现,所以我可以用模板做到这一点吗?我还不太熟悉模板语法。

Edit 1:(为了避免混淆,我在Edit 2中删除了示例模板代码)

如果我能以某种方式限制模板只允许继承QAbstractItemModel的类型,那就太好了,但我在标准c++中没有看到任何允许这样做的东西。我不会使用Boost

编辑2:我想我不是很清楚我的要求。如下:

  • 对一般情况下的基类进行操作
  • 在调试模式下强制QAbstractItemModel继承要求,而在发布模式下不受惩罚
  • 使用简单,几乎没有开销
  • 不需要修改基类或新函数

你可以让你继承的模型暴露方法分别只调用beginResetModel()和endResetModel(),然后让ModelResetter调用这些方法

我讨厌回答我自己的问题,但几天后,我整理了一个基于模板的解决方案,满足了我的所有需求。这是我的第一个从头开始的模板类。下面是实现:

//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
}

谢谢你的帮助!

相关内容

  • 没有找到相关文章

最新更新