Dynamische Datenstrukturen mit intelligenten Zeigern

Content

Im Normalfall gibt es keinen Bedarf für ungeschützte Zeiger. Stattdessen lohnt sich der konsequente Einsatz entsprechender RAII-Klassen.

Relevant sind hier zunächst die folgenden Typen und Funktionen zum Anlegen eines Objekts mit einem entsprechenden Zeiger darauf:

std::unique_ptr<T>

std::make_unique<T>(...) mit Parametern für den Konstruktor

ab C++14

std::unique_ptr<T[]>

std::make_unique<T[]>(size) mit der Dimensionierung des Arrays

ab C++14

std::shared_ptr<T>

std::make_shared<T>(...) mit Parametern für den Konstruktor

ab C++11

std::shared_ptr<T[]>

noch ohne zugehörige Unterstützung von std::make_shared<T[]>

ab C++17

std::shared_ptr<T[]>

std::make_shared<T[]>(size) mit der Dimensionierung des Arrays

ab C++20

Um diese Typen und Funktionen etwas näher kennenzulernen, lohnt es sich, auch klassische Datenstrukturen vereinfacht nachzuimplementieren. Im Rahmen dieser Sitzung beschäftigen wir uns hier mit (der Einfachheit halber) Hash-Tabellen mit einer festdimensionierten Bucket-Table:

Fragen und Aufgabe

Vorlage

#include <iostream>
#include <string>
#include "Hash.hpp"

int main() {
   Hash<std::string, unsigned int> hash(32);
   std::string town; unsigned int population;
   while (std::cin >> town && std::cin >> population) {
      if (!hash.insert(std::make_pair(town, population))) {
	 std::cerr << "insertion of " << town << " failed." << std::endl;
      }
   }
   hash.for_each([](auto& object) {
      std::cout << object.first << " " << object.second << std::endl;
   });
}
Freiburg 227590
Heidelberg 159914
Karlsruhe 309999
Konstanz 83789
Mannheim 304781
Stuttgart 628032
Tübingen 88347
Ulm 123953