Estoy haciendo una clase y quiero volver a mi clase dentro de un método. Mi clase tiene un rapidjson::Document objeto.

Usted puede ver los problemas anteriores aquí: LNK2019: «símbolo externo sin resolver» con rapidjson

Como descubrí, rapidjson evitar realizar cualquier tipo de copia de la Document objeto y, a continuación, la copia predeterminada de la clase que contiene un Document objeto no se pudo. Estoy tratando de definir mi propio Constructor de Copia, pero necesito realizar una copia del objeto. Vi un camino a hipotéticamente copiar el objeto con .Accept() método, pero está volviendo a mí un montón de errores en el interior de la rapidjson::Document clase:

error C2248: «no se puede acceder miembro privado declarado en la clase `rapidjson::GenericDocument’

Este es mi Constructor de Copia:

jsonObj::jsonObj(jsonObj& other)
{
    jsonStr = other.jsonStr;
    message = other.message;

    //doc = other.doc;
    doc.Accept(other.doc);

    validMsg = other.validMsg;
}

He encontrado en el código de la biblioteca (línea 52-54) que «Copy constructor is not permitted«.

Esta es mi clase:

class jsonObj {
    string jsonStr;
    Document doc; 

public:
    jsonObj(string json);
    jsonObj(jsonObj& other);

    string getJsonStr();
};

El método:

jsonObj testOBJ()
{
    string json = "{error:null, message:None, errorMessage:MoreNone}";
    jsonObj b(json);
    return b; //It fails here if I return a nested class with a rapidjson::Document in it. Returning NULL works
}

Entonces, ¿cómo realizar una copia de la Document elemento?

  • La lectura de la documentación en esta página de la wiki guía del usuario para rapidjson, a mí me parece que usted tendrá que repensar la forma en que se redactan los jsonObj clase. Si desea hacer una copia de la rapidJson documento, a continuación, tendrá que asignar un nuevo documento y, a continuación, de forma explícita copia del documento antiguo para el nuevo documento resultante en dos documentos diferentes con los mismos datos. Así que usted tendrá que tener un constructor de copia, cesión, etc. para jsonObj. Puede que la necesidad de repensar la arquitectura y el uso de rapidJson.
  • Ya tengo una Copia y Asignar los Constructores, pero nose cómo copiar el Document objeto sin analizar la cadena json cada vez. Necesito una clase que contiene la rapidjson de la biblioteca porque me estoy haciendo una biblioteca de C++ y necesito exponer el json parser fuera con el contenedor, así que tengo que volver a mi clase a través de un método con el Document en ella. =/
  • Creo que la única manera de copiar el documento objeto es hacer el análisis de lo contrario corre en la copia profunda versus copia superficial con duplicados punteros y quién es dueño de qué problema de asignación de memoria. rapidJson parece estar diseñado para una sola instancia de cualquier documento en particular por lo que su contenedor deberá utilizar mover la semántica y no copia de la semántica. A mí me parece que usted está tratando de ir en contra de la arquitectura y el diseño de rapidJson que es por eso que sugiero que repensar su arquitectura o buscar alternativas para rapidJson.
  • Después de leer la pregunta anterior y esta estoy empezando a pensar que a @RichardChambers es de la derecha con su comentario en el otro lado una cosa más, yo estaba pensando en lugar de utilizar el documento en un anidada class crear sin Document miembro y creará cuando se alcance tal vez eso va a permitir que otro Document instance?
  • Una opción que se debe investigar es el uso de un Document puntero con shared_ptr o alguna similar mecanismo contador de referencias. Yo no estoy familiarizado con rapidJson sin embargo, mi impresión de lo que he leído es que un Document es un contenedor que es similar a una variable de JavaScript para el uso de shared_ptr como una forma de proporcionar un identificador de un objeto en un recolector de basura de la memoria de la piscina parece razonable.
  • Para aquellos interesados, Document ahora soporta C++11 de mover la semántica (como de cometer 1950efd6760fc89a074ae5b989e560edded92578), cortesía de su servidor. Sin embargo, esto no ayuda a la OP en la implementación de un constructor de copia para los objetos que contienen un Documento de valor.
  • Está volviendo jsonObj de las funciones de la única situación donde usted necesita jsonObj ser replicable?
  • Sí, porque la clase es el único lugar en el que se utiliza el elemento del Documento. Muchas gracias por tu info, por cierto.

InformationsquelleAutor SysDragon | 2014-03-28

4 Comentarios

  1. 1

    Repositorio https://github.com/rjeczalik/rapidjson
    tiene la DeepCopy parche que puede ayudarle a copiar un documento a otro.

    • Gracias pero el parche not worked for me (error on IsString` en la línea 447) al intentar realizar una copia de: doc.Accept(other.doc);
    • Cuidado para crear un caso de prueba (es decir, en gist.github.com o pastebin)?
    • También hay otro parche mencionado en github.com/pah/rapidjson/issues/1#issuecomment-39079113
    • el IsString se trataba de un problema diferente. La solución funciona, gracias.
  2. 11

    Utilizar el CopyFrom método en un nuevo Documento:

    rapidjson::Document inDoc;    //source document
    rapidjson::Document outDoc;   //destination document
    outDoc.CopyFrom(inDoc, outDoc.GetAllocator());

    Me prueba este enfoque y los cambios realizados en el documento de salida no tuvo ningún efecto en el documento de entrada. Asegúrese de que el CopyFrom método se da el documento de la salida del colocador.

    • También funciona con los no-tipos de Documentos, siempre que el Objeto puede ser convertido a un Valor. Value v = ...; outDoc.CopyFrom(v, outDoc.GetAllocator());
  3. 0

    He creado este método para copiar objetos de documento y funciona muy bien para mí:

    static void copyDocument(rapidjson::Document & newDocument, rapidjson::Document & copiedDocument) {
        rapidjson::StringBuffer strbuf;
        rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
        newDocument.Accept(writer);
        std::string str = strbuf.GetString();
        copiedDocument.Parse<0>(str.c_str());
    }
    • El análisis no es rápido tho.
  4. 0

    debe utilizar (const) de referencia como tipo de retorno(intenta guardar documentos nuevos en el creador de la clase), usted no puede copiar los documentos, es decir, no puede volver por el valor, ya que implícitamente se intenta utilizar movilidad constructor de copia

Dejar respuesta

Please enter your comment!
Please enter your name here