首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Qt -传递QJsonObject或QJsonArray的引用

Qt -传递QJsonObject或QJsonArray的引用
EN

Stack Overflow用户
提问于 2014-04-23 05:02:16
回答 2查看 7.3K关注 0票数 1

我正在使用和Qt支持Json格式数据编辑器。我想传递QJsonObject或QJsonArray引用参数给函数。

这样做是可行的:

代码语言:javascript
复制
void makeJsonData(QJsonObject &obj) {
  obj.insert("key", 1234);
}

//call makeJsonData()
QJsonObject jobj;
makeJsonData(jobj);
int keysize = jobj.keys().size(); //1, OK.

但不是这样的:

代码语言:javascript
复制
//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的引用?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-23 06:28:21

我发现有几种方法可以解决你的问题:

选项1 (如我的评论中提到的)

动态强制转换可以这样使用:

代码语言:javascript
复制
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 (编译器支持、性能问题等等)。

我查看了我的机器上的Qt头,据我所知,QJsonObjectQJsonArray并不真正继承任何东西,因此沿着将void*更改为基本类型的路线,以保持类型检查的外观是行不通的。

我要做的是:

  • 做两种不同的方法。一个用于处理数组,另一个用于处理对象。他们有不同的方法和不同的事情可以做,所以这对我来说是有意义的。您甚至可以保留相同的名称,这样它们就会被重载。
  • 有另一种方法,里面有你平常的东西。假设您的函数试图向传递的数组或对象添加一些数据。创建一个创建数据的方法(即QJsonObject createJsonData()),并在上面提到的两个方法中调用它。

这样做的目的是在保持类型检查的同时减少代码的重复。处理这两种情况的额外方法所花费的时间可能远远少于在无意中将代码传递到void*指针之后所花费的调试代码的时间。

选项3

或者,您可以使用QJsonValue,将函数的返回类型更改为QJsonValue,并使其在不修改原始对象的情况下返回新对象。此外,QJsonValue类有那些有趣的isArray/isObject方法,您可以使用这些方法来做前面提到的事情。举个例子:

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

老实说,我更喜欢这种模式,但我知道有理由采用您刚才提到的方式,例如避免不必要的内存分配。

票数 2
EN

Stack Overflow用户

发布于 2021-12-30 03:32:14

您可能需要添加以下内容:

代码语言:javascript
复制
#include <QJsonArray>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23235122

复制
相关文章

相似问题

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