--- /dev/null
+CC := c++
+CFLAGS = -std=c++98 -Wall -Wextra -Werror -Wpedantic
+
+ifneq ("$(wildcard .debug)","")
+ CFLAGS += -g
+endif
+
+RM := rm -f
+
+INCDIR := inc
+INCDIR += $(addsuffix /inc, $(SUBPROJECTS));
+ifneq ($(INCLUDE),)
+ INCLUDE := $(addprefix -I, $(INCDIR))
+endif
+
+SRCDIR := .
+
+SOURCES := main.cpp \
+ Base.cpp \
+ A.cpp \
+ B.cpp \
+ C.cpp \
+
+SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES))
+
+OBJECTS := $(SOURCES:.cpp=.o)
+
+NAME := dynacast
+
+all : $(NAME)
+
+debug : .debug
+ $(MAKE) all
+
+nodebug :
+ $(RM) .debug
+ $(MAKE) re
+
+.% :
+ $(MAKE) fclean
+ touch $@
+
+$(NAME) : $(OBJECTS)
+ $(CC) $(CFLAGS) -o $@ $^ $(LINKS)
+
+%.o : %.cpp
+ $(CC) $(CFLAGS) -o $@ -c $< $(INCLUDE)
+
+clean :
+ $(RM) $(OBJECTS)
+
+fclean : clean
+ $(RM) $(NAME)
+
+re : fclean
+ $(MAKE) all
--- /dev/null
+#include "Base.h"
+#include "A.h"
+#include "B.h"
+#include "C.h"
+#include <iostream>
+#include <cstdlib>
+#include <ctime>
+
+Base *generate(void)
+{
+ static bool is_seeded = 0;
+
+ if (!is_seeded)
+ {
+ std::srand(std::time(0));
+ is_seeded = 1;
+ }
+ switch (std::rand() % 3)
+ {
+ case 0:
+ return (new (A));
+ case 1:
+ return (new (B));
+ case 2:
+ return (new (C));
+ }
+ return (NULL);
+}
+
+void identify(Base *p)
+{
+ if (dynamic_cast<A*>(p))
+ std::cout << "The pointer is to class A\n";
+ else if (dynamic_cast<B*>(p))
+ std::cout << "The pointer is to class B\n";
+ else if (dynamic_cast<C*>(p))
+ std::cout << "The pointer is to class C\n";
+}
+
+void identify(Base &r)
+{
+ Base *const p = &r;
+
+ if (dynamic_cast<A*>(p))
+ std::cout << "The reference is to class A\n";
+ else if (dynamic_cast<B*>(p))
+ std::cout << "The reference is to class B\n";
+ else if (dynamic_cast<C*>(p))
+ std::cout << "The reference is to class C\n";
+}
+
+int main(void)
+{
+ Base *p;
+
+ for (size_t i(0); i < 10; ++i)
+ {
+ p = generate();
+ identify(p);
+ identify(*p);
+ std::cout << '\n';
+ delete (p);
+ }
+ return (0);
+}