FAQ 21.08 What syntax should be used when a constructor or destructor calls a virtual function in its object?

graphics/new_icon.gif

Use the scope operator, ::.

For example, if a constructor or a destructor of class Base calls a virtual function this->f(), it should call it using Base::f() rather than merely f().

In our experience, this guideline reduces the probability that misunderstandings will introduce subtle defects, since it forces developers to explicitly state what the compiler is obliged to do anyway. In particular, when a constructor invokes a virtual member function that is attached to this object, the language guarantees that the member function that is invoked is the one associated with the class of the constructor, even if the object being constructed will eventually be an object of a derived class that has its own version of the virtual function. An analogous statement can be made for calling a virtual function from a destructor.

 #include <iostream> using namespace std; class Base { public:   Base() throw();   virtual void f() throw();   virtual ~Base() throw(); }; Base::Base() throw() {   cout << " Base::Base() calling f()\n";   f();                                               <-- 1 } void Base::f() throw() { cout << "  Base::f()\n"; } Base::~Base() { } class Derived : public Base { public:   Derived() throw();   virtual void f() throw(); }; Derived::Derived() throw() : Base() {   cout << " Derived::Derived() calling f()\n";   f();                                               <-- 2 } void Derived::f() throw() { cout << "  Derived::f()\n"; } int main() {   cout << "Creating a Derived:\n";   Derived d; } 

(1) For clarity, this should be written Base::f();

(2) For clarity, this should be written Derived::f();

The initialization list of Derived::Derived() calls Base::Base(), even if Base() isn't explicitly specified in the initialization list. During Base::Base(), the object is merely a Base object, even though it will eventually be a Derived object (see FAQ 20.14). This is why Base::f() is called from the body of Base::Base(). During the body of Derived::Derived(), however, Derived::f() is called. The output of this program is as follows.

 Creating a Derived:  Base::Base() calling f()   Base::f()  Derived::Derived() calling f()   Derived::f() 

Since developers are often somewhat surprised by this language feature, we recommend that such calls should be explicitly qualified with the scope operator, ::.



C++ FAQs
C Programming FAQs: Frequently Asked Questions
ISBN: 0201845199
EAN: 2147483647
Year: 2005
Pages: 566
Authors: Steve Summit

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net