--- /dev/null
+#include "Animal.h"
+#include <string>
+#include <iostream>
+
+Animal::Animal(std::string type)
+ : m_type(type)
+{
+ std::cout << "Animal default cstr\n";
+}
+
+Animal::Animal(const Animal &other)
+{
+ std::cout << "Animal copy cstr\n";
+ *this = other;
+}
+
+Animal::~Animal()
+{
+ std::cout << "Animal destr\n";
+}
+
+Animal &Animal::operator=(const Animal &other)
+{
+ if (this == &other)
+ return (*this);
+ return (*this);
+}
+
+// This would better be purely virtual function but the subject mandates that
+// even the base must implement this function.
+void Animal::makeSound() const
+{
+ std::cout << "BASE ANIMAL SOUNDS\n";
+}
+
+std::string Animal::getType() const
+{
+ return (m_type);
+}
--- /dev/null
+#ifndef ANIMAL_H
+# define ANIMAL_H
+
+# include <string>
+
+class Animal
+{
+ protected:
+ std::string m_type;
+
+ public:
+ Animal(std::string type = "BASE");
+ Animal(const Animal &other);
+ ~Animal();
+
+ Animal &operator=(const Animal &other);
+
+ virtual void makeSound() const;
+ std::string getType() const;
+};
+
+#endif // ANIMAL_H
--- /dev/null
+#include "Cat.h"
+#include <iostream>
+
+Cat::Cat()
+ : Animal("Cat")
+{
+ std::cout << "Cat default cstr\n";
+}
+
+Cat::Cat(const Cat &other)
+ : Animal("Cat")
+{
+ std::cout << "Cat copy cstr\n";
+ *this = other;
+}
+
+Cat::~Cat()
+{
+ std::cout << "Cat destr\n";
+}
+
+Cat &Cat::operator=(const Cat &other)
+{
+ if (this == &other)
+ return (*this);
+ return (*this);
+}
+
+void Cat::makeSound() const
+{
+ std::cout << "Meow :3\n";
+}
--- /dev/null
+#ifndef CAT_H
+# define CAT_H
+
+# include "Animal.h"
+
+class Cat : public Animal
+{
+ private:
+
+ public:
+ Cat();
+ Cat(const Cat &other);
+ ~Cat();
+
+ Cat &operator=(const Cat &other);
+
+ void makeSound() const;
+};
+
+#endif // CAT_H
--- /dev/null
+#include "Dog.h"
+#include <iostream>
+
+Dog::Dog()
+ : Animal("Dog")
+{
+ std::cout << "Dog default cstr\n";
+}
+
+Dog::Dog(const Dog &other)
+ : Animal("Dog")
+{
+ std::cout << "Dog copy cstr\n";
+ *this = other;
+}
+
+Dog::~Dog()
+{
+ std::cout << "Dog destr\n";
+}
+
+Dog &Dog::operator=(const Dog &other)
+{
+ if (this == &other)
+ return (*this);
+ return (*this);
+}
+
+void Dog::makeSound() const
+{
+ std::cout << "Bark!\n";
+}
--- /dev/null
+#ifndef DOG_H
+# define DOG_H
+
+# include "Animal.h"
+
+class Dog : public Animal
+{
+ private:
+
+ public:
+ Dog();
+ Dog(const Dog &other);
+ ~Dog();
+
+ Dog &operator=(const Dog &other);
+
+ void makeSound() const;
+};
+
+#endif // DOG_H
--- /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 \
+ Animal.cpp \
+ Cat.cpp \
+ Dog.cpp \
+ WrongAnimal.cpp \
+ WrongCat.cpp \
+
+SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES))
+
+OBJECTS := $(SOURCES:.cpp=.o)
+
+NAME := zoo
+
+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 "WrongAnimal.h"
+#include <string>
+#include <iostream>
+
+WrongAnimal::WrongAnimal(std::string type)
+ : m_type(type)
+{
+ std::cout << "WrongAnimal default cstr\n";
+}
+
+WrongAnimal::WrongAnimal(const WrongAnimal &other)
+{
+ std::cout << "WrongAnimal copy cstr\n";
+ *this = other;
+}
+
+WrongAnimal::~WrongAnimal()
+{
+ std::cout << "WrongAnimal destr\n";
+}
+
+WrongAnimal &WrongAnimal::operator=(const WrongAnimal &other)
+{
+ if (this == &other)
+ return (*this);
+ return (*this);
+}
+
+// This would better be purely virtual function but the subject mandates that
+// even the base must implement this function.
+void WrongAnimal::makeSound() const
+{
+ std::cout << "BASE ANIMAL SOUNDS\n";
+}
+
+std::string WrongAnimal::getType() const
+{
+ return (m_type);
+}
--- /dev/null
+#ifndef WRONGANIMAL_H
+# define WRONGANIMAL_H
+
+# include <string>
+
+class WrongAnimal
+{
+ protected:
+ std::string m_type;
+
+ public:
+ WrongAnimal(std::string type = "BASE");
+ WrongAnimal(const WrongAnimal &other);
+ ~WrongAnimal();
+
+ WrongAnimal &operator=(const WrongAnimal &other);
+
+ void makeSound() const;
+ std::string getType() const;
+};
+
+#endif // WRONGANIMAL_H
--- /dev/null
+#include "WrongCat.h"
+#include <iostream>
+
+WrongCat::WrongCat()
+ : WrongAnimal("WrongCat")
+{
+ std::cout << "WrongCat default cstr\n";
+}
+
+WrongCat::WrongCat(const WrongCat &other)
+ : WrongAnimal("WrongCat")
+{
+ std::cout << "WrongCat copy cstr\n";
+ *this = other;
+}
+
+WrongCat::~WrongCat()
+{
+ std::cout << "WrongCat destr\n";
+}
+
+WrongCat &WrongCat::operator=(const WrongCat &other)
+{
+ if (this == &other)
+ return (*this);
+ return (*this);
+}
+
+void WrongCat::makeSound() const
+{
+ std::cout << "Meow :3\n";
+}
--- /dev/null
+#ifndef WRONGCAT_H
+# define WRONGCAT_H
+
+# include "WrongAnimal.h"
+
+class WrongCat : public WrongAnimal
+{
+ private:
+
+ public:
+ WrongCat();
+ WrongCat(const WrongCat &other);
+ ~WrongCat();
+
+ WrongCat &operator=(const WrongCat &other);
+
+ void makeSound() const;
+};
+
+#endif // WRONGCAT_H
--- /dev/null
+#include "Animal.h"
+#include "Cat.h"
+#include "Dog.h"
+#include "WrongAnimal.h"
+#include "WrongCat.h"
+#include <iostream>
+
+int main()
+{
+ const Animal* meta = new Animal();
+ const Animal* j = new Dog();
+ const Animal* i = new Cat();
+
+ const WrongAnimal* meta2 = new WrongAnimal();
+ const WrongAnimal* i2 = new WrongCat();
+
+ std::cout << j->getType() << " " << std::endl;
+ std::cout << i->getType() << " " << std::endl;
+ i->makeSound();
+ j->makeSound();
+ meta->makeSound();
+ std::cout << i2->getType() << " " << std::endl;
+ i2->makeSound();
+ meta2->makeSound();
+ return (0);
+}