Search code examples
c++pure-virtual

Will the pure virtual function be assigned a default function?


When a class is instantiated, a virtual table pointer is created to point to its virtual table. And each virtual function is assigned a function address.

Will the pure virtual function be assigned a default function address?

class base {
public:
   virtual void func() = 0;
};

class derived : public base {
public:
   virtual void func() {
      cout << "derived func" << endl;
   }
};

int main()
{
   base *ptr = new derived();
   delete ptr;
   ptr->func();
   return 0;
}

I have run the demo on VS2017 and the error "performed a bad memory access" happened. I know that the "__cxa_pure_virtual" will be called under the Linux system. So how do I implement my "__cxa_pure_virtual"? And how can I assign the function address to my pure function?


Solution

  • Calling a method in a deleted object is undefined behaviour, so in principle anything can happen and it’s your fault, but we can explain why you saw this behaviour.

    First when you have a pure virtual function, the compiler could store a null pointer into the vtable, and when you call the function it crashes. Your compiler is helpful, it stores a pointer to a function named __cxa_pure_virtual, which is designed to crash when you call it. So a crash in this function tells you the crash was due to calling a pure virtual function. This is both more convenient for debugging, and it is safer to have a defined crash.

    Second you deleted ptr. Deleting a derived object runs the derived class destructor, then it turns the object into a base class object, then it calls the base class destructor. Ptr had a pointer for a real func() in its vtable, but the csecond of these three steps replaced it with a pointer to __cxa_pure_virtual. It seems the memory for the object was released but not overwritten so your code manages to call the pure virtual function.

    And you absolutely one hundred percent cannot implement __cxa_pure_virtual. It is already implemented. It crashes when called and that is intentional and how it should be.