Qt - 传递QJsonObject或QJsonArray的引用

时间:2014-04-23 05:02:17

标签: c++ qt qjson

我正在使用Qt treeview和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 个答案:

答案 0 :(得分:1)

我有几种方法可以解决您的问题:

选项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,但可能并不总是打开(编译器支持,性能问题等)。

我看了一下机器上的Qt标头,据我所知,QJsonObjectQJsonArray并没有真正从任何东西继承,所以沿着改变{的路线走下去为了保持类型检查的外观,基本类型{1}}将无法正常工作。

我会做的是:

  • 制作两个单独的方法。一个用于处理数组,另一个用于处理对象。他们有不同的方法和你可以做的不同的事情,所以这对我来说是有道理的。你甚至可以保持相同的名称,以便它们过载。
  • 有另一种方法,包括你常见的东西。我假设您的函数正在尝试将一些数据添加到传递的数组或对象。创建创建数据的方法(即void*)并在上述两种方法中调用它。

这个想法是在保持类型检查的同时保持代码重复。你花费一个额外的方法来处理这两种情况所花费的时间远远少于你在意外地将某些内容传递给你从未打算通过的QJsonObject createJsonData()指针后花费调试代码的时间。

选项3

或者,您可以使用void*,将函数的返回类型更改为QJsonValue,并使其返回新对象而不修改原始对象。此外,QJsonValue类有那些有趣的QJsonValue / isArray方法,您可以使用这些方法执行前面提到的操作。一个例子:

isObject

老实说,我更喜欢这种模式,但我知道有理由采用你提到的方式,比如避免无偿的内存分配。