#include #include class Animal { public: Animal() { std::cout << "constructor" << std::endl; } Animal(const Animal& other) { std::cout << "copy constructor (" << &other << ")" << std::endl; } // Note: using *virtual* does the difference here! virtual void makeSound() const { std::cout << " from " << this << std::endl; } Animal& operator= (Animal &a) { std::cout << "lol, operator= of " << this; std::cout << "(arg: " << &a << ")" << std::endl; return *this; } }; class Cow : public Animal { public: void makeSound() const { std::cout << "Mooh. from " << this << std::endl; } }; class Cat : public Animal { public: void makeSound() const { std::cout << "Meow? from " << this << std::endl; } }; void call(Animal a) { a.makeSound(); } void callref(Animal &a) { a.makeSound(); } void callptr(Animal* a) { a->makeSound(); } int main() { Cat cat; Cow cow; std::cout << "== Some animals" << std::endl; Animal animal; animal.makeSound(); std::cout << "== animal" << std::endl; call(animal); callref(animal); callptr(&animal); std::cout << "== cat" << std::endl; animal = cat; // <- lol, operator animal.makeSound(); call(cat); callref(cat); // <- meow callref(animal); // <- generic callptr(&cat); // <- meow std::cout << "== cow" << std::endl; animal = cow; // <- lol, operator animal.makeSound(); call(cow); callref(cow); // <- mooh callptr(&cow); // <- mooh std::cout << "== refs" << std::endl; Animal &aref = cat; aref.makeSound(); // <- meow aref = cow; // <- lol, operator aref.makeSound(); // <- meow, still std::cout << "== vector:" << std::endl; // Does nothing: std::vector animals = { cat, cow }; // <- Copies for (auto &a: animals) { a.makeSound(); } std::cout << "== vector:" << std::endl; // Meow? Mooh. std::vector animalptrs = { &cat, &cow }; for (auto &a: animalptrs) { a->makeSound(); } }