简体   繁体   中英

Dynamic binding for virtual functions

class base {
public:
    virtual void foo()
    {
         cout << "Base class virutal function " << endl;
     }
}

class Derived : public base {
public:
    void foo()
     {
          cout << "Derived class virtual function " << endl;


int main()
{
    Base b, *ptr;
    Derived d;

    ptr = &b;
    ptr->foo();
    ptr = &d;
    ptr->foo();
}

Hi, I have a doubt regarding dymnamic binding here. since compiler knows that when b.foo() is there it can use base virtual fumction. and when d.foo() is present it can use derived version of foo. I mean compiler has every bit of info during compile time but still literature says that which function will be used is decided at run time.

In this specific case 1 , the compiler (at least in theory) can determine which function is called in each case, and generate code to simply call the two functions directly (and when I've tested it, most compilers will optimize code like this exactly that way).

A more typical case for polymorphism would involve some sort of user input, so the function to be called can't be determined statically. For example, using your Base and Derived classes, consider something like:

int main(int argc, char **argv) {
    Base b;
    Derived d;

    Base *arr[] = {&b, &d};

    int i = atoi(argv[1]) != 0;
    arr[i]->foo();
    return 0;
}

In this case, the compiler can't determine the correct function to call statically -- depending on what you pass on the command line when you run it, it might use either the Base or the Derived version of foo() .

You also seem to have a kind-of intermediate case you started to try to include in your code, but never really completed -- you initialize ptr to point at your Base object and then your Derived object, but you never invoke a function via ptr , only directly on the objects themselves. If you did invoke the functions via the pointer, it would be harder to optimize than when working only directly with concrete objects. Fewer compilers will determine the type statically in this case, but at least some still can/will.

1 Well, almost this specific case anyway. As it stands right now, the code won't compile, because you've defined a class named base (lower-case 'b') and tried to instantiate a class named Base (upper-case 'B'). Also, your "Derived" class isn't actually derived from Base , as you presumably intended. Once those are fixed though...

In the specific example you give here, you're correct; the compiler has enough information to know which function to call at compile time. The compiler thus does not have to look up the function at run time, but this is a compiler optimization that does not affect the result of the program - the compiler is free to bypass the lookup or not.

Are you saying that compiler can notice that you cast d to Base *ptr and resolve actual function address at runtime?

If yes, where is a sample:

if (rand() > 0.5)
{
    ptr = &b;
}
else
{
    ptr = &d;
}

ptr->foo();

how can compiler know address at runtime? That's why dynamic binding is there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM