C ++ - diseño basado en un caso especial

  Ahora, la necesidad de diseñar una estructura de datos de tipo JSON hipotética, las buenas ideas por delante de usted, más o menos pensó:

Objeto { 
    "clave": booleano, 
    "clave": Número, 
    "clave": Cadena, 
    "clave": Array, 
    "clave": Objeto 
}

  Ah, parece que no hay problema, comenzó a diseñar ... no escribió mucho, puede considerar esta situación:

Objeto { 
    "clave": [{objeto}, {} de objetos, ...] 
}

  Esto significa que la estructura de clases, probablemente, llegar a ser como este:

clase Object { 
    bool boolean; 
    número doble; 
    std :: string; 
    std :: vector <Object> array; 
    Objeto Objeto; 
}

  Por supuesto, se entiende objeto es un pares de valores múltiples, y luego cambiarlo:

Valor de clase { 
público: 
    bool booleano; 
    número doble; 
    std :: string; 
    std :: vector <Object> array; 
    Objeto Objeto; 
}; 

Clase de objeto { 
público: 
    std :: vector <std :: pair <std :: string clave, valor de Valor >>> objetos; 
}

  Esta es una clase que contiene otro, para C ++, es evidente que el compilador se quejará porque la clase de valores mediante un tipo de objeto no definido, y donde el compilador no puede determinar el tamaño de las variables miembro de clase de valor.

  Sin embargo, todavía tiene una manera de utilizar el puntero, y la declaración de clase hacia adelante del objeto:

Objeto clase; 

Valor de clase { 
público: 
    bool booleano; 
    número doble; 
    std :: string; 
    std :: vector <Object> array; 
    Objeto Objeto; 
}; 

Objeto de la clase { 
público: 
    std :: vector <std :: pair <std :: string, Valor >>> objetos; 
}

  Sin embargo, en este momento y habrá un pequeño problema, por lo que si desea utilizar la interfaz de la siguiente

Objeto Objeto; 

objeto [ "ventana"] = Valor (Object ( "Color", Valor ( "azul"))); 
std :: cout << objeto [ "ventana"] GetObject () [ "color"] GetString ()..;

  no es factible, debido a que el objeto es un puntero al valor, en caso de sobrecarga [] operador sólo puede usarlo:

Objeto Objeto; 

objeto [ "ventana"] = Valor (new Object ( "Color", Valor ( "azul"))); 
std :: cout << objeto [ "ventana"] GetObject () -> operador [] ( "color") GetString ()..;

  Parece muy extraño, si solo vivo con lo que está bien, pero desde un lugar diferente habría sido mejor:

Valor de clase; 

Objeto de la clase { 
público: 
    std :: vector <std :: pair <std :: string, Valor * >>> objetos; 
} 

Clase Valor { 
público: 
    bool booleano; 
    número doble; 
    std :: string; 
    std :: vector <Object> array; 
    Objeto Objeto; 
};

  El uso se convierte en:

Objeto Objeto; 

objeto [ "ventana"] = Valor nuevo (Object ( "Color", Valor ( "azul"))); 
std :: cout << objeto [ "ventana"] -> GetObject () [ "color"] -> GetString ();

  Si desea deshacerse por completo de este problema contiene punteros tienen que hacer algún trabajo, la clase de herencia + amigo por la clase media se puede hacer para eliminar un aspecto muy perfecto, ver código abierto Microsoft cpprestsdk código JSON.

  Por supuesto, tal vez hay otras maneras de resolver este problema, pero creo que el más bello y mejor encarnan el estilo de C ++ es la clase + hereda amigo.

  Este blog sólo quiero escribir cuando empezó a escribir esta clase de problemas de diseño estructural encuentran JSON estructura / analizador, aunque sólo mencionar aquí el uso de la declaración de la clase hacia adelante, de hecho, además del tipo de problema para abrir un valor digital (Int64 -> int32 -> doble desbordamiento), problemas de rendimiento, también se ha aprendido mucho del uso de C ++. (El futuro puede ser menos uso de C ++)

  Por último, dar un constructor JSON minimalista para lograr:

#include <iostream> 
#include <vector> 
#include <string> 

Valor clase; 

clase Boolean { 
privado: 
	_boolean bool; 
pública: 
	Boolean () 
		: _boolean () {} 
	booleana (bool val) 
		: _boolean (val) 
	{ 

	} 

	bool GetVal () const { 
		volver _boolean; 
	} 

	REGVAL void (bool val) 
	{ 
		_boolean = val; 
	} 
}; 

Número de clase { 
privado: 
	doble _number; 
pública: 
	Número () 
		: _number () {} 
	Número (int val) 
		: _number (val) 
	{ 

	} 
	Número (doble val) 
		: _number (val)
	{ 

	} 

	Duplicar GetVal () const { 
		_number de retorno; 
	} 

	Void REGVAL (doble val) { 
		_number = val; 
	} 
}; 

clase String { 
privado: 
	_STRING std :: string; 
pública: 
	String () {} 
	de cadena (const char * val) 
		: _STRING (val) 
	{ 

	} 
	String (val std :: string) 
		: _STRING (val) 
	{ 

	} 
	std :: string GetVal () const { 
		_STRING retorno; 
	} 

	Void setval (val std :: string) 
	{ 
		_STRING = val; 
	} 
}; 

la clase Array {  
privado:
	std :: vector <Valor> _array; 
público:
	Array () 
		: _array () 
	{ 
	} 
	array (std :: vector <Valor> val) 
		: _array (val) 
	{ 

	} 
	std :: vector <Valor> GetVal () const 
	{ 
		_array retorno; 
	} 

	Void setval (std :: vector <Valor> val) 
	{ 
		_array = val; 
	} 
}; 


Objeto de la clase { 
	std :: vector <std :: pair <std :: string, Valor * >> _elements; 
privada: 
	typedef std :: vector <std :: pair <std :: string, Valor * >> :: iterador iterador; 

	iterador find_iter_by_key (std :: string clave) 
	{ 
		de retorno std :: find_if (_elements.begin (), _elements.end (), [y clave] (const std :: pair <std :: string, Valor *> & p) {return p.first clave ==;});

pública: 
	Object () {} 
	de objetos (clave std :: string, * Valor de valor) 
		: {{_elements clave, valor}} 
	{ 

	} 

	Valor * y operador [] (std :: string clave) 
	{ 
		volver GetValue (clave); 
	} 

	Tamaño size_t () const 
	{ 
		_elements.size retorno (); 
	} 

	Valor * y GetValue (std :: string clave) 
	{ 
		auto iter = find_iter_by_key (clave); 
		si (iter == _elements.end ()) 
			de retorno _elements.insert (iter, std :: pair <std :: string, Valor *> (tecla, nullptr)) -> segundos; 
		ITER volver> segundos; 
	}
}; 

Valor de clase { 
	v_boolean booleana; 
	V_number número; 
	V_string cadena; 
	V_array matriz; 
	V_object objeto; 

pública: 
	Valor () 
		: v_boolean (), v_number (), v_string (), v_array (), v_object () 
	{ 
	} 

	Valor (const Valor y valor) 
	{ 
		* este = valor; 
	} 

	Valor (valor booleano) 
		: v_boolean (valor), v_number (), v_string (), v_array (), v_object () 
	{ 

	} 
	Valor (int value) 
		: v_boolean (), v_number (valor), v_string (), v_array ( ), v_object () 
	{ 

	} 
	valor (valor doble) 
		: v_boolean (), v_number (valor), v_string (), v_array (), v_object ()
	{ 

	} 
	(Valor std :: string) Valor 
		: v_boolean (), v_number (), v_string (valor), v_array (), v_object () 
	{ 

	} 
	valor (Object valor) 
	valor (std :: vector <valor> valor) 
		: v_boolean (), v_number (), v_string (), v_array (valor), v_object ()
	{ 
	} 
	Valor (valor booleano) 
		: v_boolean (valor), v_number (), v_string (), v_array (), v_object () 
	{ 

	} 
	Valor (valor numérico) 
		: v_boolean (), v_number (valor), v_string (), v_array (), v_object () 
	{ 

	} 
	valor (valor de la cadena) 
		: v_boolean (), v_number (), v_string (valor), v_array (), v_object () 
	{ 

	} 
	valor (valor de matriz) 
		: v_boolean (), v_number (), v_string (), v_array (valor), v_object () 
	{ 

	}
	}
		: V_boolean (), v_number (), v_string (), v_array (), v_object (valor) 
	{ 

	} 

	bool getBoolean () const 
	{ 
		volver v_boolean.GetVal (); 

	doble obtieneNumero () const 
	{ 
		retorno v_number.GetVal (); 
	} 

	Int GetIntNumber () const { 
		return (int) v_number.GetVal (); 
	} 

	Std :: string GetString () const 
	{ 
		volver v_string.GetVal (); 
	} 

	Std :: vector <Valor> GetArray () const 
	{ 
		volver v_array.GetVal (); 
	} 

	Objeto GetObject () const 
	{ 
		v_object retorno; 
	} 

	Valor y GetValue () 
	{ 
		retorno * esto; 
	}

 
}; 

int main () 
{ 
	object Object ( "test", el nuevo valor (Object ( "ABC", el nuevo valor (123))));
	objeto [ "color"] = Valor nuevo (Array {std :: vector <valor> {Valor (String ( "rojo")), el valor (String ( "naranja")), el valor (String ( "amarilla"))} }); 
	std :: cout << objeto [ "prueba"] -> GetObject () [ "abc"] -> GetIntNumber () << '\ n'; 
	para (i automático: Object [ "color"] -> GetArray ()) 
		std :: cout << i.GetString () << " "; 
	return 0; 
}

  salida:

123 
amarillo naranja rojo

  

Supongo que te gusta

Origin www.cnblogs.com/darkchii/p/12563533.html
Recomendado
Clasificación