Главная страница | назад





Article #18715: Pure virutal function called error

 Question and Answer Database

FAQ3715C.txt   Pure virutal function called error
Category   :Compiler
Platform    :All
Product    :   Applies to all

Question:
The following class hierarchy does not work as expected :

(Simplified)

struct A
{
  virtual void f() = 0;
};

struct B : virtual public A
{
  void g()
  {
    f();
  }
};

struct C : virtual public A
{
  void f()
  {
  }
};

struct D : virtual public B, virtual public C
{
};

void main()
{
  D d;
  d.g();
}

I can compile the program without errors but at runtime
I get a "pure virtual function called" error?

Is this error correct? If so, how can I fix the problem?


Answer:
It is not an "error" to call a virtual function from a ctor or dtor --
virtual functions simply behave *differently* when called from ctors and
dtors (and *sometimes* this difference can result in a pure virtual function
call -- which is an error).

That is, the difference is that virtual functions will not behave virtually
"beyond" the current type of the object during construction or destruction.
However, this doesn't always result in a pure virtual being called.

Consider the following...

   struct A {
      virtual void func1() { }
   };

   struct B: C {
      B() { func1(); }
      virtual void func1() { }
      void func2() { func1(); }
   };

   struct C: B {
      virtual void func1() { }
   };

   int main() {
      C c; // B::func1() called during B::B().
      c.func2(); // Now, C::func1() called.
      return 0;
   };

In the above program, it wasn't an error to call func1() from B's ctor
(which executes during the construction of the C object in main).  The call
to func1() just doesn't behave as it does after the C object is fully
constructed (as when it's called via B::func2() on the following line).

A similar example could be created with a call to func1() from B::~B().

Anyway, the behavior of virtual functions in ctors and dtors is due to
"natural" C++ rules.  While B's ctor executes, the object is by definition
not yet a C, so a call to the virtual function func1() calls B's func1().
After the object is fully constructed, it is finally a honest-to-goodness C
object and so calls to func1() will call C's func1().


8/26/98 2:28:43 PM
 

Last Modified: 01-SEP-99