DIPL.-ING. MARTIN WEITZEL, 64380 ROSSDORF, GERMANY

Vega - Grieshaber 2018-04 Übung Donnerstagmittag

Zielsetzung:

Entwerfen bzw. vervollständigen Sie eine Klasse, welche eine Eigenschaften von

  • std::array (zur Compilezeit festgelegte Größe)

kombiniert mit eingen Eigenschaften von

  • std::vector (deren Member-Funktionen (soweit möglich)

Die Aufgabe soll in mehreren Schritten gelöst werden, welche sich durch die nächsten Übungsphasen hindurchziehen.

Schritt 1:

Ertstellen Sie den Header-File einer sehr einfachen Templafe-Klasse `vf_array` (für vf = "variabel-festes" Array)

Neben der üblichen Include-Guards soll diese Klasse lediglich wie folgendes enthalten:

// file: vf_array.h

#ifndef VF_ARRAY
#define VF_ARRAY

#include <cstddef>

template<typename T, std::size_t N>
class vf_array {
private:
    T data[N];
    T* filled{&data[0]};
public:
    auto max_size() const { return N; }

};

#endif

Testen Sie dieses wie folgt:

// file: vf_array_test.cpp

#include "pxtn.h"

PN_(Testing Class `vf_array`)

#include "vf_array.h"

int main() {
    vf_array<int ,12> arr1;     PX_("12", arr1.max_size());
    vf_array<double ,3> arr2;   PX_("3", arr2.max_size());
}

Schritt 2:

Fügen Sie eine Member-Funktion `push_back` hinzu, die ein weiteres Element anhängt und um diese Testen zu können eine Member-Funktion `back`, welche auf das letzte Element zugreift:


template<typename T, std::size_t N>
class vf_array {
private:
    T data[N];
    T* filled{&data[0]};
public:
    auto max_size() const { return N; }
    void push_back(const T& e) { /*TBD*/ }
    T& back() { return /*TBD*/ }
};

Testen Sie mit:

arr1.push_back(31);   PX_("31", arr1.back())
arr1.push_back(32);   PX_("32", arr1.back());
arr2.push_back(1.25); PX_("1.25", arr2.back());

Schritt 3:

Fügen Sie Member-Funktion `size` und `empty` hinzu.

  • Erstere soll die Anzahl der enthaltenen Elemente liefern.
  • Letztere soll `true` liefern, wenn keine Elemente enthalten sind.

Unter Weiterverwendung der bereits bestehenden Test-Codes könnten Sie die neuen Features wie folgt testen.

PX_("false", arr1.empty()); PX_("2", arr1.size());
PX_("false", arr2.empty()); PX_("1", arr2.size());

Testen Sie auch für einen (anfangs) leeren Container, z.B. so:

vf_array<bool, 1> arr0; PX("true", arr0.empty());
arr0.push_back(true);   PX("true", arr0.back());
                       
 PX("false", arr0.empty());


Damit die Ausgabe von Wahrheitswerten als "false" / "true" erscheint (und nicht als "0" / "1") müssen Sie am Anfang von `main` die folgende Einstellung vornehmen:

  • std::cout.setf(std::ios::boolalpha);

Schritt 4:

Fügen Sie eine zwei weitere Member-Funktionen `begin()` und `end()` hinzu, welche

  • einen Zeiger auf das erste bzw,
  • einen Zeiger hinter das letzte (gefüllte)

Element liefern.

Ist das evtl. schon ausreichend dafür, eine Range-For-Schleife über alle befüllten Elemente laufen zu lassen?

Schritt 5:

Fügen Sie in die Klasse `vf_array` die folgenden (öffentlich sichtbaren) Typedefinitionen ein:

typedef T value_type;
typedef std::size_t size_type;
typedef T* iterator;
typedef const T* const_iterator;


An dieser Stelle wird üblicherweise daran erinnert, für jedes implementierte Feature auch einen Test vorzusehen. In diesem Fall wird darauf verzichtet, da die einfachste Art und Weise einen solchen Test zu schreiben einen Vorgriff auf die Standard Type Traits erfodern würde.


Welchen Zweck könnten diese Typ-Aliase haben bzw. wann könnten sie sich als nützlich erweisen?

(Anstelle der oben verwendeten, klassischen `typedef`-Syntax dürfen Sie gerne die mit C++11 neu eingeführte `using`-Syntax verwenden.)


Falls Sie mit der Übung momentan nicht ganz fertig werden – kein Problem!
Sie können die unbearbeitenden Schritte in der nächsten Praktikumsphase abschließen.
(Oder sie kopieren diese aus der Musterlösung.)