Для чего это стоит, я нахожу, что доступ к ним через «путь», немного как дерево каталогов на диске, работает достаточно хорошо. Это взято из некоторых C# код, который я пишу (обратите внимание, что я пропустил бит из ниже класса), но идея перевести прямолинейно на C++:
sealed class Entity : IEntity
{
private readonly IDictionary<string,IEntity> m_children = new Dictionary<string,IEntity>();
private readonly IDictionary<string,dynamic> m_properties;
public string Name { get { return m_properties["Name"]; } }
public IEntity Parent { get; set; }
/// <summary>
/// Adds a child to this entity.
/// </summary>
/// <param name="child">The child to add.</param>
public void AddChild(IEntity child)
{
m_children.Add(child.Name, child);
child.Parent = this;
}
/// <summary>
/// Gets the absolute path of this entity in its tree.
/// </summary>
/// <returns>The entity's absolute path.</returns>
public string GetAbsolutePath()
{
IEntity cur = this;
var path = new LinkedList<string>();
while(cur.Parent != null)
{
path.AddFirst(cur.Name);
cur = cur.Parent;
}
path.AddFirst(".");
return string.Join("/", path);
}
/// <summary>
/// Gets another entity in this entity's tree by its absolute path (i.e. its path relative to the root entity).
/// </summary>
/// <param name="path">The absolute path to the other entity.</param>
/// <returns>The other entity, if found, or null otherwise.</returns>
public IEntity GetEntityByAbsolutePath(string path)
{
return GetRootEntity().GetEntityByRelativePath(path);
}
/// <summary>
/// Gets another entity in this entity's tree by its absolute path (i.e. its path relative to the root entity).
/// </summary>
/// <param name="path">The absolute path to the other entity, as a list of path components.</param>
/// <returns>The other entity, if found, or null otherwise.</returns>
public IEntity GetEntityByAbsolutePath(LinkedList<string> path)
{
return GetRootEntity().GetEntityByRelativePath(path);
}
/// <summary>
/// Gets another entity in this entity's tree by its path relative to this entity.
/// </summary>
/// <param name="path">The relative path to the other entity.</param>
/// <returns>The other entity, if found, or null otherwise.</returns>
public IEntity GetEntityByRelativePath(string path)
{
return GetEntityByRelativePath(new LinkedList<string>(path.Split('/')));
}
/// <summary>
/// Gets another entity in this entity's tree by its path relative to this entity.
/// </summary>
/// <param name="path">The relative path to the other entity, as a list of path components.</param>
/// <returns>The other entity, if found, or null otherwise.</returns>
public IEntity GetEntityByRelativePath(LinkedList<string> path)
{
IEntity cur = this;
while(cur != null && path.Count != 0)
{
switch(path.First())
{
case ".":
break;
case "..":
cur = cur.Parent;
break;
default:
cur = cur.GetChild(path.First());
break;
}
path.RemoveFirst();
}
return cur;
}
/// <summary>
/// Gets the root entity of this entity's tree.
/// </summary>
/// <returns>The root entity of this entity's tree.</returns>
private IEntity GetRootEntity()
{
IEntity cur = this;
while(cur.Parent != null)
{
cur = cur.Parent;
}
return cur;
}
}
Учитывая любой объект в дереве сущностей, вы можете затем обращаться к другим объектам по их абсолютному или относительному пути, например
cityA.GetEntityByRelativePath("../city:B/building:1");
Что заставляет вас думать, что 'std :: set' подходит для хранения деревьев? –
Если вы плохо разбираетесь с указателями, даже 1 опасен. Если вы с ними добры, то 1 и 100 не имеют значения. Это предложение. Я мог бы также просто получить к ним доступ через указатели, но передавать эти звуки несколько опасно и утомительно, если вы попадаете в ситуацию с большим количеством объектов, не имеет смысла! – Shahbaz