2014-04-23 5 views
0

Qt treeview 및 Qt Json 지원을 사용하여 Json 형식 데이터 편집기를 만들고 있습니다. 함수에 QJsonObject 또는 QJsonArray 참조 매개 변수를 전달하고 싶습니다.Qt - QJsonObject 또는 QJsonArray의 참조 전달

이 작동 : 나는 두 QJsonObject의 참조를 사용할 수있는 방법

//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 모양() 만 복사 매개 변수 .. 과 :

void makeJsonData(QJsonObject &obj) { 
    obj.insert("key", 1234); 
} 

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

하지만이에 매개 변수 유형이 하나 인 QJsonArray?

+0

'QJsonObject'와'QJsonArray' 둘 다에 대한 메소드에서'dynamic_cast <>'와 함께 매개 변수 타입으로'void *'를 사용하면 작동합니다 (포인터 타입으로 변환하면 캐스트 실패시 null을 반환합니다). '.toObject()'를 할 필요없이'QJsonValue'와'QJsonArray'를 모두 넘겨 줄 수있을 것입니다. 요구. –

+0

@LosFrijoles 빠른 답장을 보내 주셔서 감사합니다! –

답변

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이 필요합니다 (컴파일러 지원, 성능 문제 등). 그렇게하기 위해 기본 유형에 void* 변화의 경로를 아래로 가고,

나는 내 컴퓨터에 Qt는 헤더에보고했고 지금까지 내가 말할 수있는, QJsonObjectQJsonArray은 정말 아무것도로부터 상속하지 않습니다 형식 검사의 형태를 유지하는 것은 효과가 없습니다. 내가 할 것이 무엇

이 될 것입니다 :

  • 두 개의 별도의 방법을 확인하십시오. 하나는 배열을 처리하고 하나는 객체를 처리하기위한 것입니다. 그들은 당신이 할 수있는 다른 방법과 다른 것들을 가지고 있습니다, 그래서 이것은 나에게 의미가 있습니다. 동일한 이름을 유지하여 과부하가 걸릴 수도 있습니다.
  • 일반적인 방법으로 다른 방법을 사용하십시오. 귀하의 함수가 일부 데이터를 전달하려고하는 배열이나 객체에 추가하려고한다고 가정합니다. 이 데이터 (예 : 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"; 
    } 
} 

솔직히이 패턴을 선호하지만, 난 당신이 불필요한 메모리 할당을 피하는 등의 언급 한 길을가는 이유가 알고있다.

+0

와우, 고마워, 내가 본 최고의 답변. 나는 당신의 선택권을보고 검사 할 것입니다 3. 감사합니다. 좋은 하루 되세요. –