首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ModelResetter RAII对象

ModelResetter RAII对象
EN

Stack Overflow用户
提问于 2013-03-07 17:10:22
回答 2查看 226关注 0票数 2

我有一个自定义代理模型,当一个新的列/行被添加到它的源模型时,它偶尔会对自己进行大修。从文档中可以看出,在这样一个操作的开始和结束时调用QAbstractItemModel::beginResetModel()QAbstractItemModel::endResetModel()是正确的方法。不幸的是,我的大修函数有几个可能的退出点,我只知道我会忘记在每个出口点调用endResetModel,因为它变得更复杂了。

因此,我想创建一个简单的RAII类,它将在构建时调用beginResetModel,然后在销毁时调用endResetModel,如下所示:

代码语言:javascript
复制
class ModelResetter
{
public:
    ModelResetter(QAbstractItemModel* model) : m_model(model)
    {
        m_model->beginResetModel();
    }
    ~ModelResetter()
    {
        m_model->endResetModel();
    }

private:
    QAbstractItemModel* m_model;
};

问题是beginResetModel()endResetModel()QAbstractItemModel中都是protected。在我的ModelResetter继承的模型中将friend class声明为似乎没有帮助,因为我试图与基类交互。

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

编辑1: (我删除了编辑2中的示例模板代码以避免混淆)

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

编辑2:我想我对我的需求不是很清楚。下面是它们:

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

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-08 19:23:49

我不想回答我自己的问题,但几天后,我找到了一个基于模板的解决方案,满足了我所有的需求。为我的第一个从零开始的模板类。以下是实现:

代码语言:javascript
复制
//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;
};

和用法:

代码语言:javascript
复制
//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
EN

Stack Overflow用户

发布于 2013-03-08 14:55:08

您可以让继承的模型公开方法分别调用beginResetModel()和endResetModel(),然后让ModelResetter调用这些方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15277447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档