#include <iostream>
#include <list>

using namespace std;

struct Base
{
	int a;

	Base(int in = 0)
	  : a{ in }
	{}
	virtual void print() { cout << a << endl; }
};

struct Derived : Base
{
	int b;

	void print() { cout << b << endl; }
};

class Animal
{
      public:
	virtual void sound() = 0;

	virtual ~Animal(){};
};

class Wolf : public Animal
{
	int size;

      public:
	Wolf(int size)
	  : size{ size }
	{}

	void sound() { cout << "Howl!" << size << endl; }
	~Wolf() { cout << "Wolf howls goodbye" << endl; }
};
class Chicken : public Animal
{
	int tastiness;

      public:
	Chicken(int tastiness)
	  : tastiness{ tastiness }
	{}
	void sound()
	{
		cout << "Kikeriki!"
		     << "This Chicken is" << tastiness << "times tasty!"
		     << endl;
	}
	~Chicken() { cout << "Chicken kikeriks goodbye" << endl; }
};

class Kangaroo : public Animal
{
	unique_ptr<Animal> passenger;

      public:
	Kangaroo(unique_ptr<Animal>&& p)
	  : passenger{ move(p) }
	{}
	void sound()
	{
		cout << "Kangaroo's bag says :";
		passenger->sound();
	}
};

class Shark
{
	list<unique_ptr<Animal>> Iveeaten;
};

int
main()
{
	list<unique_ptr<Animal>> zoo;
	zoo.push_back(unique_ptr<Wolf>(new Wolf(12)));
	zoo.push_back(make_unique<Chicken>(1000));
	zoo.push_back(make_unique<Kangaroo>(make_unique<Chicken>(500000)));
	zoo.push_back(make_unique<Chicken>(1000));
	zoo.push_back(make_unique<Chicken>(1000));

	for (auto& a : zoo) {
		a->sound();
	}
	int count = 0;
	for (auto& a : zoo) {
		if (dynamic_cast<Chicken*>(a.get()))
			count++;
	}
	cout << "num of chickens: " << count << endl;

#if 0
	Base base = 2;
	Derived d;
	d.b=5;
	d.a = 6;
	base.print();
	d.print();

	Base* i = &base;
	i->print();
	i = &d;
	i->print();
	cout << sizeof(d) << endl;
#endif
}
