diff --git a/20210204/hp-2020ws-p4.pdf b/20210204/hp-2020ws-p4.pdf
index 21bff505fd5fa6ca5d8913a694261a19ac6f55fd..1f17c91ca4ab823ea9f3781f79b36d148b0d36c6 100644
Binary files a/20210204/hp-2020ws-p4.pdf and b/20210204/hp-2020ws-p4.pdf differ
diff --git a/20210204/hp-2020ws-p4.tex b/20210204/hp-2020ws-p4.tex
index c5eb30c709d75fa9925470f9ad9b8ac1eb6c3cb0..bb2a1a765df1d1bcf2cf122b32fc68e0df2b75fa 100644
--- a/20210204/hp-2020ws-p4.tex
+++ b/20210204/hp-2020ws-p4.tex
@@ -90,6 +90,13 @@
       \end{lstlisting}
       (Den Backslash am Ende der ersten Zeile entfällt,
       wenn Sie den ganzen Befehl in eine einzige Zeile schreiben.)
+    \item
+      \textbf{Abgabe:}
+      Ihre Quelltexte mit den Lösungen der Praktikumsaufgabe schicken Sie bitte
+      per E-Mail an \file{peter.gerwinski@hs-bochum.de}
+      mit dem \textbf{Betreff:} \lstinline[style=terminal]{eif7booD}
+      unter Angabe von Name, Matrikel-Nummer,
+      Studiengang (MI/MP/TI) und Studienmodell (KIA/KIS/GS).
   \end{itemize}
 
   \bigskip
diff --git a/20210204/objects-11a.c b/20210204/objects-11a.c
new file mode 100644
index 0000000000000000000000000000000000000000..8be8d4eb28ccc2ea950d601a2b1da4c2a38270dc
--- /dev/null
+++ b/20210204/objects-11a.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+union t_object;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+} t_base;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this)  /* virtuelle Methode des Objekts t_integer */
+{
+  printf ("Integer: %d\n", this->integer.content);
+}
+
+void print_string (t_object *this)  /* virtuelle Methode des Objekts t_string */
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i)  /* Konstruktor des Objekts t_integer */
+{
+  t_object *p = malloc (sizeof (t_integer));  /* Anforderung von Speicherplatz */
+  p->integer.type = T_INTEGER;
+  p->integer.print = print_integer;  /* Zuweisung der virtuellen Methode */
+  p->integer.content = i;  /* Initialisierung des Objekts */
+  return p;
+}
+
+t_object *new_string (char *s)  /* Konstruktor des Objekts t_string */
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i]);
+
+  return 0;
+}
diff --git a/20210204/objects-11b.c b/20210204/objects-11b.c
new file mode 100644
index 0000000000000000000000000000000000000000..3b3a798df03399f69f6704ac1391d22781c6fd30
--- /dev/null
+++ b/20210204/objects-11b.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+union t_object;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+} t_base;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this, char *comment)  /* virtuelle Methode des Objekts t_integer */
+{
+  printf ("Integer: %d\n", this->integer.content);
+  printf ("Kommentar: %s\n", comment);
+}
+
+void print_string (t_object *this)  /* virtuelle Methode des Objekts t_string */
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i)  /* Konstruktor des Objekts t_integer */
+{
+  t_object *p = malloc (sizeof (t_integer));  /* Anforderung von Speicherplatz */
+  p->integer.type = T_INTEGER;
+  p->integer.print = print_integer;  /* Zuweisung der virtuellen Methode */
+  p->integer.content = i;  /* Initialisierung des Objekts */
+  return p;
+}
+
+t_object *new_string (char *s)  /* Konstruktor des Objekts t_string */
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i]);
+
+  return 0;
+}
diff --git a/20210204/objects-11c.c b/20210204/objects-11c.c
new file mode 100644
index 0000000000000000000000000000000000000000..50c5c3acfe2e66f7b847f4120419c6044447ee1f
--- /dev/null
+++ b/20210204/objects-11c.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+union t_object;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+} t_base;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, char *comment);
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this, char *comment)  /* virtuelle Methode des Objekts t_integer */
+{
+  printf ("Integer: %d\n", this->integer.content);
+  printf ("Kommentar: %s\n", comment);
+}
+
+void print_string (t_object *this)  /* virtuelle Methode des Objekts t_string */
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i)  /* Konstruktor des Objekts t_integer */
+{
+  t_object *p = malloc (sizeof (t_integer));  /* Anforderung von Speicherplatz */
+  p->integer.type = T_INTEGER;
+  p->integer.print = print_integer;  /* Zuweisung der virtuellen Methode */
+  p->integer.content = i;  /* Initialisierung des Objekts */
+  return p;
+}
+
+t_object *new_string (char *s)  /* Konstruktor des Objekts t_string */
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i]);
+
+  return 0;
+}
diff --git a/20210204/objects-11d.c b/20210204/objects-11d.c
new file mode 100644
index 0000000000000000000000000000000000000000..283a3ec68063dbb6da72efa2cf64e20897dff296
--- /dev/null
+++ b/20210204/objects-11d.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+union t_object;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+} t_base;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, char *comment);
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this, char *comment)  /* virtuelle Methode des Objekts t_integer */
+{
+  printf ("Integer: %d\n", this->integer.content);
+  printf ("Kommentar: %s\n", comment);
+}
+
+void print_string (t_object *this)  /* virtuelle Methode des Objekts t_string */
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i)  /* Konstruktor des Objekts t_integer */
+{
+  t_object *p = malloc (sizeof (t_integer));  /* Anforderung von Speicherplatz */
+  p->integer.type = T_INTEGER;
+  p->integer.print = print_integer;  /* Zuweisung der virtuellen Methode */
+  p->integer.content = i;  /* Initialisierung des Objekts */
+  return p;
+}
+
+t_object *new_string (char *s)  /* Konstruktor des Objekts t_string */
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i], "Dies ist ein Test.");
+
+  return 0;
+}
diff --git a/20210204/objects-11e.c b/20210204/objects-11e.c
new file mode 100644
index 0000000000000000000000000000000000000000..47184be39f60e173479bf93e40361b77d93a2bb0
--- /dev/null
+++ b/20210204/objects-11e.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+union t_object;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, char *comment);
+} t_base;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, char *comment);
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this, char *comment)  /* virtuelle Methode des Objekts t_integer */
+{
+  printf ("Integer: %d\n", this->integer.content);
+  printf ("Kommentar: %s\n", comment);
+}
+
+void print_string (t_object *this)  /* virtuelle Methode des Objekts t_string */
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i)  /* Konstruktor des Objekts t_integer */
+{
+  t_object *p = malloc (sizeof (t_integer));  /* Anforderung von Speicherplatz */
+  p->integer.type = T_INTEGER;
+  p->integer.print = print_integer;  /* Zuweisung der virtuellen Methode */
+  p->integer.content = i;  /* Initialisierung des Objekts */
+  return p;
+}
+
+t_object *new_string (char *s)  /* Konstruktor des Objekts t_string */
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i], "Dies ist ein Test.");
+
+  return 0;
+}
diff --git a/20210204/objects-11f.c b/20210204/objects-11f.c
new file mode 100644
index 0000000000000000000000000000000000000000..6c4673803a82e0f4ab055d536cdc3b12f37afc2b
--- /dev/null
+++ b/20210204/objects-11f.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+union t_object;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, char *comment);
+} t_base;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, char *comment);
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, char *comment);
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this, char *comment)  /* virtuelle Methode des Objekts t_integer */
+{
+  printf ("Integer: %d\n", this->integer.content);
+  printf ("Kommentar: %s\n", comment);
+}
+
+void print_string (t_object *this, char *comment)  /* virtuelle Methode des Objekts t_string */
+{
+  printf ("String: \"%s\"\n", this->string.content);
+  (void) comment;
+}
+
+t_object *new_integer (int i)  /* Konstruktor des Objekts t_integer */
+{
+  t_object *p = malloc (sizeof (t_integer));  /* Anforderung von Speicherplatz */
+  p->integer.type = T_INTEGER;
+  p->integer.print = print_integer;  /* Zuweisung der virtuellen Methode */
+  p->integer.content = i;  /* Initialisierung des Objekts */
+  return p;
+}
+
+t_object *new_string (char *s)  /* Konstruktor des Objekts t_string */
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i], "Dies ist ein Test.");
+
+  return 0;
+}
diff --git a/20210204/objects-11g.c b/20210204/objects-11g.c
new file mode 100644
index 0000000000000000000000000000000000000000..80b6e8a012850dab7c62fe326a7e76104f7ff035
--- /dev/null
+++ b/20210204/objects-11g.c
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+union t_object;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, char *comment);
+} t_base;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, char *comment);
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, char *comment);
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this, char *comment)  /* virtuelle Methode des Objekts t_integer */
+{
+  printf ("Integer: %d\n", this->integer.content);
+  printf ("Kommentar: %s\n", comment);
+}
+
+void print_string (t_object *this)  /* virtuelle Methode des Objekts t_string */
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+void print_string (t_object *this, char *comment)  /* virtuelle Methode des Objekts t_string */
+{
+  printf ("String: \"%s\"\n", this->string.content);
+  printf ("Kommentar: %s\n", comment);
+}
+
+t_object *new_integer (int i)  /* Konstruktor des Objekts t_integer */
+{
+  t_object *p = malloc (sizeof (t_integer));  /* Anforderung von Speicherplatz */
+  p->integer.type = T_INTEGER;
+  p->integer.print = print_integer;  /* Zuweisung der virtuellen Methode */
+  p->integer.content = i;  /* Initialisierung des Objekts */
+  return p;
+}
+
+t_object *new_string (char *s)  /* Konstruktor des Objekts t_string */
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i], "Dies ist ein Test.");
+
+  return 0;
+}
diff --git a/20210204/objects-11h.c b/20210204/objects-11h.c
new file mode 100644
index 0000000000000000000000000000000000000000..717922a974268fb97ee62cea074ef99545b34c08
--- /dev/null
+++ b/20210204/objects-11h.c
@@ -0,0 +1,81 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+union t_object;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, void *data);
+} t_base;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, void *data);
+  int content;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this, void *data);
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this, void *data)  /* virtuelle Methode des Objekts t_integer */
+{
+  printf ("Integer: %d\n", this->integer.content);
+  if (data)
+    {
+      char *comment = data;
+      printf ("Kommentar: %s\n", comment);
+    }
+}
+
+void print_string (t_object *this, void *data)  /* virtuelle Methode des Objekts t_string */
+{
+  printf ("String: \"%s\"\n", this->string.content);
+  (void) data;
+}
+
+t_object *new_integer (int i)  /* Konstruktor des Objekts t_integer */
+{
+  t_object *p = malloc (sizeof (t_integer));  /* Anforderung von Speicherplatz */
+  p->integer.type = T_INTEGER;
+  p->integer.print = print_integer;  /* Zuweisung der virtuellen Methode */
+  p->integer.content = i;  /* Initialisierung des Objekts */
+  return p;
+}
+
+t_object *new_string (char *s)  /* Konstruktor des Objekts t_string */
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i], "Dies ist ein Test.");
+
+  return 0;
+}
diff --git a/20210204/objects-11i.c b/20210204/objects-11i.c
new file mode 100644
index 0000000000000000000000000000000000000000..bda518a83af77239e526a86b329abf34d10ffd2f
--- /dev/null
+++ b/20210204/objects-11i.c
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define T_BASE    0
+#define T_INTEGER 1
+#define T_STRING  2
+
+union t_object;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+} t_base;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+  int content;
+  char *comment;
+} t_integer;
+
+typedef struct
+{
+  int type;
+  void (* print) (union t_object *this);
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+void print_integer (t_object *this)  /* virtuelle Methode des Objekts t_integer */
+{
+  printf ("Integer: %d\n", this->integer.content);
+  if (this->integer.comment)
+    printf ("Kommentar: %s\n", this->integer.comment);
+}
+
+void print_string (t_object *this)  /* virtuelle Methode des Objekts t_string */
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_object *new_integer (int i, char *comment)  /* Konstruktor des Objekts t_integer */
+{
+  t_object *p = malloc (sizeof (t_integer));  /* Anforderung von Speicherplatz */
+  p->integer.type = T_INTEGER;
+  p->integer.print = print_integer;  /* Zuweisung der virtuellen Methode */
+  p->integer.content = i;  /* Initialisierung des Objekts */
+  p->integer.comment = comment;  /* Initialisierung des Objekts */
+  return p;
+}
+
+t_object *new_string (char *s)  /* Konstruktor des Objekts t_string */
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->string.type = T_STRING;
+  p->string.print = print_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42, "Dies ist ein Test."),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.print (object[i]);
+
+  return 0;
+}
diff --git a/20210204/objects-13.c b/20210204/objects-13.c
index 81ef279b060e0b6290194fdeda8c3330cb716cdd..8cbf2d435ce6642568a809660b8d63866963450a 100644
--- a/20210204/objects-13.c
+++ b/20210204/objects-13.c
@@ -57,7 +57,7 @@ t_object *new_integer (int i)
 t_object *new_string (char *s)
 {
   t_object *p = malloc (sizeof (t_string));
-  p->integer.vmt = &vmt_string;
+  p->string.vmt = &vmt_string;
   p->string.content = s;
   return p;
 }
diff --git a/20210204/objects-13a.c b/20210204/objects-13a.c
new file mode 100644
index 0000000000000000000000000000000000000000..83d01abade9685d4f591570e03ea080fbde8b6d2
--- /dev/null
+++ b/20210204/objects-13a.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+union t_object;
+struct t_vmt;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+} t_base;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+typedef struct t_vmt
+{
+  void (* print) (union t_object *this);
+} t_vmt;
+
+void print_integer (t_object *this)
+{
+  printf ("Integer: %d\n", this->integer.content);
+}
+
+void print_string (t_object *this)
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_vmt vmt_integer = { print_integer };
+t_vmt vmt_string = { print_string };
+
+t_object *new_integer (int i)
+{
+  t_object *p = malloc (sizeof (t_integer));
+  p->base.vmt = &vmt_integer;
+  p->integer.content = i;
+  return p;
+}
+
+t_object *new_string (char *s)
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->base.vmt = &vmt_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.vmt->print (object[i]);
+
+  return 0;
+}
diff --git a/20210204/objects-14.c b/20210204/objects-14.c
new file mode 100644
index 0000000000000000000000000000000000000000..acd20b5af1a6a425da4d6af47e03185e224e3461
--- /dev/null
+++ b/20210204/objects-14.c
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+union t_object;
+struct t_vmt;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+} t_base;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+typedef struct t_vmt
+{
+  void (* print) (union t_object *this);
+} t_vmt;
+
+void print_integer (t_object *this)
+{
+  printf ("Integer: %d\n", this->integer.content);
+}
+
+void print_integer_with_comment (t_object *this, char *comment)
+{
+  printf ("%s: %d\n", comment, this->integer.content);
+}
+
+void print_string (t_object *this)
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_vmt vmt_integer = { print_integer };
+t_vmt vmt_string = { print_string };
+
+t_object *new_integer (int i)
+{
+  t_object *p = malloc (sizeof (t_integer));
+  p->base.vmt = &vmt_integer;
+  p->integer.content = i;
+  return p;
+}
+
+t_object *new_string (char *s)
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->base.vmt = &vmt_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.vmt->print (object[i]);
+
+  print_integer_with_comment (object[1], "Die Antwort lautet");
+
+  return 0;
+}
diff --git a/20210204/objects-15.c b/20210204/objects-15.c
new file mode 100644
index 0000000000000000000000000000000000000000..b0ef5540e78cd00ce615ae19b34a23157d9f13ef
--- /dev/null
+++ b/20210204/objects-15.c
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+union t_object;
+struct t_vmt;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+} t_base;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+  int content;
+} t_integer;
+
+typedef struct
+{
+  struct t_vmt *vmt;
+  char *content;
+} t_string;
+
+typedef union t_object
+{
+  t_base base;
+  t_integer integer;
+  t_string string;
+} t_object;
+
+typedef struct t_vmt
+{
+  void (* print) (union t_object *this);
+} t_vmt;
+
+void print_integer (t_object *this)
+{
+  printf ("Integer: %d\n", this->integer.content);
+}
+
+void print_integer_with_comment (t_object *this, char *comment)
+{
+  printf ("%s: %d\n", comment, this->integer.content);
+}
+
+void print_string (t_object *this)
+{
+  printf ("String: \"%s\"\n", this->string.content);
+}
+
+t_vmt vmt_integer = { print_integer };
+t_vmt vmt_string = { print_string };
+
+t_object *new_integer (int i)
+{
+  t_object *p = malloc (sizeof (t_integer));
+  p->base.vmt = &vmt_integer;
+  p->integer.content = i;
+  return p;
+}
+
+t_object *new_string (char *s)
+{
+  t_object *p = malloc (sizeof (t_string));
+  p->base.vmt = &vmt_string;
+  p->string.content = s;
+  return p;
+}
+
+int main (void)
+{
+  t_object *object[] = { new_integer (42),
+                         new_string ("Hello, world!"),
+                         NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->base.vmt->print (object[i]);
+
+  print_integer_with_comment (object[0], "Die Antwort lautet");
+
+  return 0;
+}
diff --git a/20210204/objects-16.cpp b/20210204/objects-16.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ea40a139bacadb6ce4de30312bb0c1b6c21d9c8e
--- /dev/null
+++ b/20210204/objects-16.cpp
@@ -0,0 +1,52 @@
+#include <stdio.h>
+
+struct TBase
+{
+  virtual void print () = 0;
+};
+
+struct TInteger: TBase
+{
+  int content;
+  virtual void print ();
+  TInteger (int i);
+};
+
+struct TString: TBase
+{
+  char *content;
+  virtual void print ();
+  TString (char *s);
+};
+
+void TInteger::print ()
+{
+  printf ("Integer: %d\n", content);
+}
+
+void TString::print ()
+{
+  printf ("String: \"%s\"\n", content);
+}
+
+TInteger::TInteger (int i)
+{
+  content = i;
+}
+
+TString::TString (char *s)
+{
+  content = s;
+}
+
+int main (void)
+{
+  TBase *object[] = { new TInteger (42),
+                      new TString ("Hello, world!"),
+                      NULL };
+
+  for (int i = 0; object[i]; i++)
+    object[i]->print ();
+
+  return 0;
+}