Qt - 传递 QJsonObject 或 QJsonArray 的引用
Qt - passing reference of QJsonObject or QJsonArray
我正在制作具有Qt树视图和Qt Json支持的Json格式数据编辑器。我想将 QJsonObject 或 QJsonArray 引用参数传递给函数。
这有效:
void makeJsonData(QJsonObject &obj) {
obj.insert("key", 1234);
}
//call makeJsonData()
QJsonObject jobj;
makeJsonData(jobj);
int keysize = jobj.keys().size(); //1, OK.
但不是这个:
//QJsonValue, because it can handle both QJsonObject and QJsonArray
void makeJsonData(QJsonValue &obj) {
obj.toObject().insert("key", 1234); //obj is QJsonObject
}
//call makeJsonData()
QJsonObject jobj;
makeJsonData(QJsonValue::fromVariant(jobj)); //fromVariant() to cast QJsonObject to QJsonValue
int keysize = jobj.keys().size(); //0, Fail.
看起来QJsonValue::toObject((只是复制参数。如何将 QJsonObject 和 QJsonArray 的引用与一种参数类型一起使用?
几种方法可以解决您的问题:
选项 1(如我的评论中所述(
动态强制转换可以像这样使用:
bool makeJsonData(void* obj) {
QJsonObject* asObj = dynamic_cast<QJsonObject*>(obj);
QJsonArray* asArray = dynamic_cast<QJsonArray*>(obj);
if (asObj) {
//do what you would if it were an object
}
else if (asArray) {
//do what you would if it were an array
}
else {
//cast fail. Returning false to tell the caller that they passed bad data
//an alternate (probably better) would be to throw an exception
return false;
}
}
选项 2
老实说,我觉得与void*
的这项业务是错误的方式。做void*
事情几乎总是一种代码气味(它删除了编译时检查,使我们免于踩到自己的脚(,在这种情况下,我认为你这样做的方式需要工作。此外,dynamic_cast
需要 RTTI,而 RTTI 可能并不总是打开(编译器支持、性能问题等(。
查看了机器上的Qt标头,据我所知,QJsonObject
和QJsonArray
并没有真正继承任何东西,因此沿着将void*
更改为基本类型的路线以保持类型检查的外观将不太有效。
我会做的是这样的:
- 创建两个单独的方法。一个用于处理数组,一个用于处理对象。他们有不同的方法和你可以做的不同的事情,所以这对我来说是有意义的。您甚至可以保留相同的名称,以便它们过载。 有
- 另一种方法,里面有你常见的东西。我假设您的函数正在尝试向传递的数组或对象添加一些数据。制作一个创建数据的方法(即
QJsonObject createJsonData()
(,并在上面提到的两个方法中调用它。
这个想法是减少代码重复,同时仍然保留类型检查。您花费在制作一个额外方法来处理这两种情况上的时间可能远远少于您在意外地将某些内容传递给您从未打算传递的void*
指针后调试代码所花费的时间。
选项 3
或者,您可以使用QJsonValue
,将函数的返回类型更改为QJsonValue
,并使其返回新对象而不修改原始对象。此外,QJsonValue
类具有那些有趣的isArray
/isObject
方法,您可以使用它们来执行前面提到的操作。举个例子:
QJsonValue makeJsonData(const QJsonValue& val) {
if (val.isObject()) {
QJsonObject obj = val.toObject();
//do your stuff, modifying obj as you please (perhaps calling another method so that this can have less repetition
return QJsonValue(obj);
}
else if (val.isArray()) {
QJsonArray arr = val.toArray();
//do your stuff, modifying arr as you please (perhaps calling another method so that this can have less repetition
return QJsonValue(arr);
}
else {
throw "Invalid Value Type";
}
}
老实说,我更喜欢这种模式,但我知道有理由按照您提到的方式进行,例如避免不必要的内存分配。
您可能需要添加以下内容:
#include <QJsonArray>
- 将对象数组的引用传递给函数
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 何时在引用或唯一指针上使用移动语义
- 如何在c++中使用引用实现类似python的行为
- 编译C++时未定义的引用
- Ctypes wstring通过引用传递
- c++r值引用应用于函数指针
- 理解c++中的引用
- C++取消引用指针.为什么会发生变化
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 强制转换为引用类型
- 引用一个已擦除类型(void*)的指针
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 具有默认值的引用获取函数
- 如何使用基类指针引用派生类成员
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- Qt - 传递 QJsonObject 或 QJsonArray 的引用