CS253: Software Development with C++

Spring 2018

Virtual Functions

See this page as a slide show

CS253 Virtual Functions

Pointers

class Base {
  public:
    void foo() { cout << "β\n"; }
};

class Derived : public Base {
  public:
    void foo() { cout << "Δ\n"; }
};

int main() {
    Derived d;
    Base *b = &d;
    b->foo();
    return 0;
}
β

b->foo() called the .foo() method of Base. Why? Because b is a Base *.

References

class Base {
  public:
    void foo() { cout << "β\n"; }
};

class Derived : public Base {
  public:
    void foo() { cout << "Δ\n"; }
};

int main() {
    Derived d;
    Base &b = d;
    b.foo();
    return 0;
}
β

Same result with a reference. References are just a variety of pointers, so that’s expected.

Unsurprising

These results are unsurprising. If your pointer is a Generic *, then p->method() calls a method of Generic.

But what if that’s not what you want? What if you have a pointer of type Generic *, but it’s really pointing to an object of type Specific? It can do that, if Specific is a subclass (derived class) of Generic. You might want p->method() to call the method of the object’s actual type, as opposed to its apparent type.

Virtual

class Base {
  public:
    virtual void foo() { cout << "β\n"; }
};

class Derived : public Base {
  public:
    virtual void foo() { cout << "Δ\n"; }
};

int main() {
    Derived d;
    Base *b = &d;
    b->foo();
    return 0;
}
Δ

That’s different!

Virtual

class Base {
  public:
    virtual void foo() { cout << "β\n"; }
};

class Derived : public Base {
  public:
    virtual void foo() { cout << "Δ\n"; }
};

int main() {
    Derived d;
    Base &b = d;
    b.foo();
    return 0;
}
Δ

That’s different!

Terminology

People often call these “virtual functions”, though a good O-O programmer might call them “virtual methods”. A method is a function, after all.

Not using virtual methods:

Using virtual methods:

Cost

There is, of course, a cost to all of this.

Virtual Dtor

class Base {
  public:
    virtual void foo() { cout << "β\n"; }
};

class Derived : public Base {
  public:
    virtual void foo() { cout << "Δ\n"; }
    string s;                   // Look--a data member!
};

int main() {
    Base *b = new Derived;
    b->foo();
    delete b;
    return 0;
}
c.cc:15: warning: deleting object of polymorphic class type 'Base' which has 
   non-virtual destructor might cause undefined behavior
Δ

Contamination

If a method is declared virtual in the base class, it’s automatically virtual in all derived classes. It’s virtual all the way down.

However, I generally repeat the virtual declaration in each subclass to remind the reader.

User: Guest

Check: HTML CSS
Edit History Source

Modified: 2018-04-24T16:57

Apply to CSU | Contact CSU | Disclaimer | Equal Opportunity
Colorado State University, Fort Collins, CO 80523 USA
© 2018 Colorado State University
CS Building