#include #include class Base { public: virtual int f() const { std::cout << "Base::f()\n"; return 1; } virtual void f(std::string s) const { std::cout << "Base::f(" << s << ")\n"; } virtual void g() const { std::cout << "Base::g()\n"; } }; class Derived1 : public Base { public: void g() const { std::cout << "Derived1::g()\n"; } }; class Derived2 : public Base { public: // Overriding a virtual function: int f() const { std::cout << "Derived2::f()\n"; return 2; } }; class Derived3 : public Base { public: // Cannot change return type: // void f() const{ std::cout << "Derived3::f()\n";} }; class Derived4 : public Base { public: // Change argument list: not really overriding int f(int i ) const { std::cout << "Derived4::f(" << i << ")\n"; return 4; } }; int main() { std::string s("hello"); Derived1 d1; int x = d1.f(); d1.f(s); Derived2 d2; x = d2.f(); //! d2.f(s); // string version hidden d2.Base::f(s); // string version hidden Derived4 d4; x = d4.f(20); //! x = d4.f(); // f() version hidden x = d4.Base::f(); // f() version hidden //! d4.f(s); // string version hidden d4.Base::f(s); Base& br = d4; // Upcast slicing problem //br.f(1); // Derived version unavailable br.f(); // Base version available br.f(s); // Base version abailable return 0; }