Question

I am currently learning about dynamic binding and virtual functions. This is from Accelerated C++, chapter 13:

[...] We want to make that decision at run time. That is, we want the system to run the right function based on the actual type of the objects passed to the function, which is known only at run time.

I don't understand the very idea that the type of an object can be unknown at compile time. Isn't it obvious from the source code?

Was it helpful?

Solution

Not at all. Consider this example:

struct A {
  virtual void f() = 0;
};

struct B : A {
  virtual void f() { std::cerr << "In B::f()\n"; }
};

struct C : A {
  virtual void f() { std::cerr << "In C::f()\n"; }
};

static void f(A &a)
{
  a.f(); // How do we know which function to call at compile time?
}

int main(int,char**)
{
  B b;
  C c;
  f(b);
  f(c);
}

When the global function f is compiled, there is no way to know which function it should call. In fact, it will need to call different functions each time. The first time it is called with f(b), it will need to call B::f(), and the second time it is called with f(c) it will need to call C::f().

OTHER TIPS

C++ has a concept of pointers, where the variable holds only a "handle" to an actual object. The type of the actual object is not known at compile-time, only at runtime. Example:

#include <iostream>
#include <memory>

class Greeter {
public:
    virtual void greet() = 0;
};

class HelloWorld : public Greeter {
public:
    void greet() {std::cout << "Hello, world!\n";}
};

class GoodbyeWorld : public Greeter {
public:
    void greet() {std::cout << "Goodbye, world!\n";}
};

int main() {
    std::unique_ptr<Greeter> greeter(new HelloWorld);
    greeter->greet();    // prints "Hello, world!"
    greeter.reset(new GoodbyeWorld);
    greeter->greet();    // prints "Goodbye, world!"
}

See also: Vaughn Cato's answer, which uses references (which is another way to hold a handle to an object).

Say you have a pointer to base class pointing to a derived object

Base *pBase = new Derived;

// During compilation time, compiler looks for the method CallMe() in base class
// if defined in class Base, compiler is happy, no error
// But when you run it, the method call gets dynamically mapped to Derived::CallMe()

// ** provided CallMe() is virtual method in Base and derived class overrides it.

pBase->CallMe(); // the actual object type is known only during run-time.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top