← SEARCHABLE ARCHIVE
C / C++ · 2026-07-01

C++ von den Grundlagen bis zum Profi — Folge 10

STL-Container und std::optional richtig auswählen

INTERACTIVE READING MODE →

Die in diesem Blog verfassten Artikel wurden mit dem Ziel erstellt, zu unterrichten. Außerdem können die Informationen im Artikel falsch sein, also seien Sie bitte vorsichtig.

Es gibt verschiedene Arten von Daten im Spiel, wie z. B. Gruppenlisten, Monstersuchen, Spawn-Warteschlangen und Tötungsaufzeichnungen. Alle Daten können mit einem einzigen Vektor aufgelöst werden, aber der Code ist klarer, wenn Sie eine Datenstruktur verwenden, die für den Zweck geeignet ist.

vector

std::vectorist ein dynamisches Array, das zusammenhängenden Speicher verwendet.

std::vector<int> damages;
damages.reserve(10);

damages.push_back(10);
damages.emplace_back(20);

for (int damage : damages)
{
    std::cout << damage << '\n';
}

Das Element ist[]oderat()Ansatz. at()prüft die Reichweite, aber[]wird nicht geprüft.

Wenn die Kapazität des Vektors nicht ausreicht, erfolgt eine Neuzuweisung durch Erstellen eines neuen größeren Speichers und Verschieben vorhandener Elemente. Zu diesem Zeitpunkt werden möglicherweise Zeiger, Referenzen und Iteratoren, die auf vorhandene Elemente verweisen, ungültig.

unordered_map

Um einen Artikel schnell anhand der Artikel-ID zu finden, verwenden Sie eine Hash-Tabelle.std::unordered_mapDas passt zu dir.

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()Wenn es fehlschlägtend()kehrt zurück. Sie sollten einen Iterator nicht dereferenzieren, ohne zu prüfen, ob er gefunden wurde.

Warteschlange und Stapel

Die Warteschlange ist eine FIFO-Struktur, bei der der zuerst eingehende Wert zuerst ausgegeben wird. Es passt gut in die Spawn-Warteschlange.

if (!spawnQueue.empty())
{
    auto monster = spawnQueue.front();
    spawnQueue.pop();
}

Der Stapel ist eine LIFO-Struktur, bei der der letzte Wert zuerst ausgegeben wird. Es kann verwendet werden, um kürzliche Kills aufzuzeichnen oder rückgängig zu machen.

if (!killHistory.empty())
{
    int lastMonsterId = killHistory.top();
    killHistory.pop();
}

pop gibt keinen Wert zurück. Sie müssen zuerst den Wert mit front oder top abrufen und dann pop aufrufen.

optional

Wenn möglicherweise keine Suchergebnisse vorhanden sind, wird stattdessen ein spezieller Fehlerwert angezeigtstd::optionalverwendet werden kann.

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';
}

Der Rückgabetyp zeigt, dass möglicherweise ein Wert vorhanden ist oder nicht. Blindes Beantworten einer leeren Optionvalue()Sie sollten nicht anrufen. Sie müssen zunächst die Existenz prüfen.

Das Kriterium für die Auswahl einer Datenstruktur ist nicht die Mode, sondern der Verwendungszweck. Eine geordnete Liste kann als Vektor, die Schlüsselsuche als unordered_map, die Wartereihenfolge als Warteschlange, der aktuelle Datensatz als Stapel und das Fehlen eines Werts als optional ausgedrückt werden.