C++ de los fundamentos al dominio — Lección 10
Elegir un contenedor STL y opcional
Los artículos escritos en este blog fueron creados con el objetivo de enseñar. Además, la información del artículo puede ser incorrecta, así que tenga cuidado.
Hay diferentes tipos de datos en el juego, como listas de grupos, búsquedas de monstruos, colas de generación y registros de muertes. Todos los datos se pueden resolver con un solo vector, pero el código es más claro si utiliza una estructura de datos que se adapte al propósito.
vector
std::vectores una matriz dinámica que utiliza memoria contigua.
std::vector<int> damages;
damages.reserve(10);
damages.push_back(10);
damages.emplace_back(20);
for (int damage : damages)
{
std::cout << damage << '\n';
}
El elemento es[]oat()acercarse. at()comprueba el alcance, pero[]no está marcado.
Si la capacidad del vector es insuficiente, se produce la reasignación creando una nueva memoria más grande y moviendo elementos existentes. En este momento, los punteros, referencias e iteradores que apuntan a elementos existentes pueden quedar invalidados.
unordered_map
Para buscar rápidamente un artículo por ID de artículo, utilice una tabla hash.std::unordered_mapEsto te conviene.
std::unordered_map<int, Item> itemDatabase;
itemDatabase.emplace(1, Item{1, "Sword", 100});
auto iter = itemDatabase.find(1);
if (iter != itemDatabase.end())
{
std::cout << iter->second.name << '\n';
}
find()si fallaend()regresa. No debe eliminar la referencia a un iterador sin verificar si se encontró.
cola y pila
La cola es una estructura FIFO donde el valor que entra primero sale primero. Encaja bien en la cola de generación.
if (!spawnQueue.empty())
{
auto monster = spawnQueue.front();
spawnQueue.pop();
}
La pila es una estructura LIFO donde el último valor sale primero. Se puede utilizar para registrar o deshacer muertes recientes.
if (!killHistory.empty())
{
int lastMonsterId = killHistory.top();
killHistory.pop();
}
pop no devuelve un valor. Primero debes obtener el valor con front o top y luego llamar a pop.
optional
Si es posible que no haya resultados de búsqueda, en lugar de un valor de error especialstd::optionalse puede utilizar.
std::optional<Item> FindItem(int id) const
{
auto iter = itemDatabase.find(id);
if (iter == itemDatabase.end())
{
return std::nullopt;
}
return iter->second;
}
if (auto item = FindItem(1))
{
std::cout << item->name << '\n';
}
El tipo de retorno revela que puede haber o no un valor. Responder a ciegas a un opcional vacíovalue()No deberías llamar. Primero debes comprobar su existencia.
El criterio para elegir una estructura de datos no es la moda, sino el uso previsto. Una lista ordenada se puede expresar como vector, la búsqueda de claves como mapa_desordenado, el orden de espera como cola, el registro reciente como pila y la ausencia de valor como opcional.