Pool of QObject instances
Pool of QObject instances
我有一个问题,我不知道如何解决…
我们有泛型对象池。当对象被请求时,池返回QSharedPointer
到第一个可用的实例,并指定自定义Deleter。删除器只在QSharedPointer
实例refcount为0时返回对象到池。对于普通对象,一切都工作得很好。当在Qt 5中编译时,它也可以很好地用于QObject
继承者。
然而,如果在Qt 4.6中编译-问题开始:当第二次请求相同的对象时-应用程序退出并出现错误:
"QSharedPointer:指针xxx已经有引用计数"
我写了简单的test:
QObject* obj = new QObject();
QSharedPointer<QObject> p(obj, deleter); // deleter here does nothing
p.clear();
QSharedPointer<QObject> p2(obj, deleter); // this crashes the app
在Qt 4.6中编译时肯定会失败。再次:在QT 5.x中工作良好。
查看Qt源代码,它揭示了4.6在QObject
中初始化内部ref计数器,当这个QObject
被用作QSharedPointer
参数时。这样做是为了确保没有两个智能指针指向同一个对象,它只在析构函数中被重置。
当QObject
实例包装成智能指针时,Qt5不检查ref计数器的值,因此它工作。
有人知道旧Qt版本的任何解决方案吗?是否有任何方法可以完全重置内部Qt状态,包括refcounter ?
假设你有一个池来避免内存分配和释放,你应该只分配一次内存,然后在请求和返回"new"对象时显式调用构造函数和析构函数。
/* deleter calls destructor explicitly when return object to pool */
void deleter(QObject *object) {
object->~QObject();
mark_as_available();
}
/* allocate (one object) pool memory without calling constructor*/
QObject *object = ::operator new(sizeof(QObject));
/* request object - calling constructor on already allocated memory */
mark_as_taken();
return QSharedPointer(::new (object) QObject, &deleter);
/* deallocate pool memory without calling destructor */
::operator delete(object);
您只能从QObject
创建QSharedPointer
一次之后,您将需要复制现有的QSharedPointer
实例
根据Qt 4和5文档:
QSharedPointer 将在指针超出作用域时删除它所持有的指针,前提是没有其他QSharedPointer对象引用它。
所以你的样本行为如下:
QObject* obj = new QObject();
QSharedPointer<QObject> p(obj, deleter); // deleter here does attach to "obj"
p.clear(); //this does cause delete of "obj"
QSharedPointer<QObject> p2(obj, deleter); // using deleted pointer will cause crash (if you are lucky XD)
使用QWeakPointer不会删除QObject
和断言:
"QSharedPointer:指针xxx已经有引用计数"
是为了确保您不会意外创建多个删除器(这确实很安全,我使用的是QSharedPointer
,但意味着QWeakPointer
),但它有时确实会妨碍。
- 删除 QSharedPointer 指向的 QObject
- QObject::连接无法将信号连接到*this*对象的插槽
- 调试符号中缺少 QObject 类信息(编辑但存在其他 Qt 类)
- QML/C++/QObject Struct Copy
- QObject::d eleteLater在我的Qt测试中没有像预期的那样调用
- 具有 QObject 继承的单例 - Qt
- QObject::连接不起作用 - 使用函数语法找不到信号
- 是否可以在单独的线程中将 QObject 设置为 QML 上下文属性?
- 智能指针作为 QObject::d eleteLater() 的替代品
- Shiboken2 qobject.h:46:10:致命:找不到'QtCore/qobjectdefs.h'文件
- 在 dll 中为 qLibrary 编译 qobject 时出错
- 将复制构造函数设置为默认值在继承自 QObject 时不起作用
- 我应该使用多个角色还是一个角色,将实际属性推迟到将数据包装/公开为其属性的QObject
- 在另一个线程上发出 QObject 信号的正确方法?
- 为什么 QObject::d isconnect(const QMetaObject::Connection &connection) 采用 const 参数并打算修改它?
- 在 QObject 方法中生成 QWidgets
- 我可以自动处理继承 QObject 的仅标头对象吗?
- QT 库 QObject::connect: 无法连接 (null)::done() 到 MainWindow::upd
- QObject::connect 有太多的参数
- Pool of QObject instances