Is virtual function table really necessary for C++

OOP polymorphism 

  In OOP languages, a base-class object pointer can do function call according to the actual type of the object. Let's see an example in Java.

public class Animal{
    public void spark(){
        System.out.println("spark");
    }  
}
public class Dog extends Animal{
    public void spark(){
        System.out.println("WangWang");
    }
}
public class Cat extends Animal{
    public void spark(){
        System.out.println("MiaoMiao");
    }
}

public class Main{
    public static void main(String[] args){
        Animal[] animals=new Animal[3];
        animals[0]=new Dog();
        animals[1]=new Cat();
        animals[2]=new Animal();
        for(Animal it:animals){
            it.spark()
        }
    }
}

it will output

WangWang
MiaoMiao
spart

That's "polymorphism". 

C++virtual function

  Above codes is very natual for Java programmers. However in C++, you can't get such "polymorphism" without the "virtual" keyword decorating the functions. Without "virtual", C++ will output

spark
spark
spark

  Take a look at  <the virtual table> if you don't yet know about virtual table. This article explains why "virtual" came out, and how virtual function is supported by virtual table.

Why virtual table

  Why does C++ use virtual table? 

  =>Because C++ compiler does not know the actual function address

     --->Why?

  =>Because C++ compiler does not know the exact type(Cat? Dog? Animal?) of the oject the pointer "panimal" points to

         ---Why? Is that any way compiler can figure out the object type?

  =>Yes! Using "object type tracking"!

object type tracking

 Let's consider the sources where an object pointer gets its value. 2 sources indeed.

1. another pointer
2. address of class instance

Where does "another pointer" get its value? Eventually, there's a pointer that gets its value from "class instance".

So, via tracking the assignment thread backwards to the original source object

  => the compiler is able to figure out the exact type of a pointer.

  =>the compiler knows the address of the exact function being called

  =>no virtual table is needed.

Object type tracking saves both virtual table memery and virtual table pointer of each class instances.

Where does object type tracking not work

Library Linking.

If a library function returns a base-class pointer, there's no way for the compiler to track back to the original source object. The compiler can probably adapt to library code and none-library code. For library classes that are exported out, use virtual table. For other classes, just track theire object type to save memory. 

PS: a stackoverflow post I started talking about this problem: click here. Sadly it's proved that Object type tracking failed when there's conditional assignment.

int x;
cin >> x;
Animal* p;
if (x == 10)
    p = new Cat();
else
    p = new Dog();

The compiler can't figure out what's the type of p.

原文地址:https://www.cnblogs.com/linghuaichong/p/4108849.html