liveBook · Manning

Vtable

As explained in 100 C++ Mistakes and How to Avoid Them

A virtual function table is a compiler-generated table containing addresses used to dispatch a class's virtual functions.

A vtable, or virtual function table, is a compiler-generated class table containing addresses for virtual functions. An object uses a pointer to locate the appropriate implementation at runtime. section 8.9

During construction, dispatch follows the part of the object initialized so far. Base-class construction completes first; derived-class table pointers are established only as construction proceeds. This explains why virtual calls from constructors use base-class behavior instead of the final derived override. section 8.9

Mistake: calling a virtual function from a constructor

A Person constructor calls print(), which calls virtual getHonorific(). Constructing a GradStudent prints “Aimee”, then “second year Aimee”, then “candidate Aimee”, because each constructor sees only its initialized class level. Remove virtual calls from constructors and let construction finish before calling print(). section 8.9

Figure 8.1 A three-level hierarchy showing construction order

Trace the A–B–C construction order and see when each class table becomes active. section 8.9

Listing 8.17 Calling virtual functions from a constructor
class Person {
private:
    std::string name;
public:
    Person(const std::string& name) : 
        name(name) { print(); }    #A
    void print() const { std::cout << getHonorific() << name << '\n'; }
    const std::string getName() const { return getHonorific() + name; }
    virtual std::string getHonorific() const { return ""; }
};
 
class Student : public Person {
private:
    std::string year;
public:
    Student(const std::string& name, const std::string& year) : Person(name), 
        year(year) { print(); }
    std::string getHonorific() const { return year + " "; }
};
 
class GradStudent : public Student {
private:
    bool candidate;
public:
    GradStudent(const std::string& name, const std::string& year,
        bool candidate) : Student(name, year), candidate(candidate) 
        { print(); }                                         #1
       
        
    std::string getHonorific() const {
        return candidate ? "candidate " : ""; }
};
 
int main() {
    GradStudent aimee("Aimee", "second year", true);
    return 0;
}

Inspect the constructor-based virtual-call example, then compare its output with the safer constructor-free version. section 8.9

How 100 C++ Mistakes and How to Avoid Them covers it

How deep it goes
Provides a conceptual table-and-pointer model, but defers the complex implementation details.
Examples
Uses a Person–Student–GradStudent hierarchy, constructor output, and revised constructors without virtual calls.
What it assumes
Assumes virtual functions and inheritance while building a conceptual model of construction-time dispatch.
What you can do after
Diagnose constructor dispatch output and remove unsafe virtual calls from construction paths.
How it connects
Connects virtual functions with inheritance, constructors, object construction order, and runtime dispatch.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 C++ Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.