Circumventing the Virtual Mechanism

In some cases, we want to prevent dynamic binding of a call to a virtual function; we want to force the call to use a particular version of that virtual. We can use the scope operator to do so. For example, this code:

//  calls the version from the base class regardless of the dynamic type of baseP
double undiscounted = baseP->Quote::net_price(42);

calls the Quote version of net_price regardless of the type of the object to which baseP actually points. This call will be resolved at compile time.


Image Note

Ordinarily, only code inside member functions (or friends) should need to use the scope operator to circumvent the virtual mechanism.


Why might we wish to circumvent the virtual mechanism? The most common reason is when a derived-class virtual function calls the version from the base class. In such cases, the base-class version might do work common to all types in the hierarchy. The versions defined in the derived classes would do whatever additional work is particular to their own type.


Image Warning

If a derived virtual function that intended to call its base-class version omits the scope operator, the call will be resolved at run time as a call to the derived version itself, resulting in an infinite recursion.



Exercises Section 15.3

Exercise 15.11: Add a virtual debug function to your Quote class hierarchy that displays the data members of the respective classes.

Exercise 15.12: Is it ever useful to declare a member function as both override and final? Why or why not?

Exercise 15.13: Given the following classes, explain each print function:

class base {
public:
   string name() { return basename; }
   virtual void print(ostream &os) { os << basename; }
private:
   string basename;
};
class derived : public base {
public:
   void print(ostream &os) { print(os); os << " " << i; }
private:
   int i;
};

If there is a problem in this code, how would you fix it?

Exercise 15.14: Given the classes from the previous exercise and the following objects, determine which function is called at run time:

base bobj;     base *bp1 = &bobj;   base &br1 = bobj;
derived dobj;  base *bp2 = &dobj;   base &br2 = dobj;

(a) bobj.print();

(b) dobj.print();

(c) bp1->name();

(d) bp2->name();

(e) br1.print();

(f) br2.print();


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset