En lugar de tratar de escribir cada nodo fuertemente basado en el número de padres que ha, organizar el código como una estructura de árbol:
class Element
{
public:
std::string Name;
std::map<std::string, std::string, std::less<std::string> > Attributes;
std::list<Element> Children;
};
Su interfaz pública probablemente verá muy diferente de este. Solo intento mostrar el diseño de tipo general.
Realmente no necesita las funciones Nodo o Atributo, a menos que necesite iterar sobre ellas en una colección junto con Elementos. Es una característica útil para las bibliotecas XML DOM, pero si solo está tratando de crear una estructura de datos, no tiene que seguir el diseño DOM al pie de la letra.
De hecho, si sólo va para una estructura de datos genérica, es posible que quieran una bolsa de propiedades:
#include<map>
#include<string>
#include<iostream>
class PropertyBag;
typedef std::map<std::string, PropertyBag> PropertyMap;
class PropertyBag : public PropertyMap
{
public:
PropertyBag(const std::string& value)
: value(value)
{
}
PropertyBag& operator=(const std::string& value)
{
this->value = value;
return *this;
}
operator std::string&() { return value; }
private:
std::string value;
friend PropertyMap::mapped_type& PropertyMap::operator[](const PropertyMap::key_type&);
PropertyBag() { }
};
void SomeFunction(const std::string& value)
{
std::cout << value << "\n";
}
int main(int argc, char* argv[])
{
PropertyBag config("configuration root");
config["child1"] = "value1";
config["child1"]["subchild1"] = "value2";
SomeFunction(config["child1"]);
SomeFunction(config["child1"]["subchild1"]);
return 0;
}
sólo hablar de la sintaxis, también se puede tratar de conseguir difícil con sobrecarga operator()
y/o métodos de encadenamiento:
PropertyBag& SomeMethod(const std::string& someParam)
{
// do something here...
return *this;
}
PropertyBag& operator()(const std::string& p1, const std::string& p2)
{
// ...
return *this;
}
// ...
Configuration config1("root")
.SomeMethod("p1")
.SomeMethod("p2");
Configuration config2("root")
("Something", "blah")
("sizzle", "V2");
Imagino que cuanto menos duplicación de texto/código, mejor. Cuanto más cerca pueda hacer que su código tenga una sintaxis como JSON o YAML, mejor.
Una vez que sale C++ 0x, puede tener opciones mucho más simples disponibles para usted.También puede consultar el boost::assign library para obtener una sintaxis de inicialización fácil de usar en su estructura de datos.
También puede buscar en el boost::any library un tipo de datos que puede usar como valor, en lugar de cadenas (admite un método seguro para insertar cualquier valor, siempre que lo extraiga del mismo tipo).
+1, ahora que entiendo la pregunta mejor. Pensé que estabas tratando de implementar una biblioteca XML :) –