Summary
"Pure virtual function called" is the dying message of the occasional crashed C++ program. What does it mean? You can find a couple of simple, well-documented explanations out there that apply to problems easy to diagnose during postmortem debugging. There
is also another rather subtle bug that generates the same message. If you have a mysterious crash associated with that message, it might well mean your program went indirect on a dangling pointer. This article covers all these explanations.
......
Build 'em Up, Tear 'em Down
When you construct an instance of a derived class, what happens, exactly? If the class has a vtbl, the process goes something like the following.
Step 1: Construct the top-level base part:.
- Make the instance point to the base class's vtbl.
- Construct the base class instance member variables.
- Execute the body of the base class constructor.
Step 2: Construct the derived part(s) (recursively):
- Make the instance point to the derived class's vtbl.
- Construct the derived class instance member variables.
- Execute the body of the derived class constructor.
Destruction happens in reverse order, something like this:
Step 1: Destruct the derived part:
- (The instance already points to the derived class's vtbl.)
- Execute the body of the derived class destructor.
- Destruct the derived class instance member variables.
Step 2: Destruct the base part(s) (recursively):
- Make the instance point to the base class's vtbl.
- Execute the body of the base class destructor.
- Destruct the base class instance member variables.
附实例:
#include <iostream> class Base{ public: virtual ~Base() { std::cout<<"Base::~Base()"<<std::endl; sleep(30); } virtual void do_sth() = 0; }; class Derived: public Base{ public: virtual ~Derived(){ std::cout<<"Derived::~Derived()"<<std::endl; } virtual void do_sth() { std::cout<<"Derived::do_sth()"<<std::endl; } }; void* mydo(void *p) { sleep(10); Base * _p = (Base*) p; _p->do_sth(); } int main(){ Base * pb = new Derived(); pthread_t thread; pthread_create(&thread,NULL,mydo,pb); delete pb; sleep(10000); return 0; }