How is it possible to call a pure virtual function?

Started by
12 comments, last by rpg_code_master 18 years, 8 months ago
I have had the odd windows error saying that a pure virtual function has been called. Since then, I have ran through my head possible ways of actually doing so, but to no avail. So my question is this:- How do you go about calling a pure virtual function?
Advertisement
Could you post what the error is? (copy/paste)


Is the error during run-time or compile-time?

Does this happen in your own programs, or you have seen it happen in some other program?
It’s never happened in any of my own programs, just in the odd other program. The error message is literally something like, "ERROR: Pure virtual function call".
Quote:Original post by rpg_code_master
It’s never happened in any of my own programs, just in the odd other program. The error message is literally something like, "ERROR: Pure virtual function call".


Personally I don't understand how you could call a pure virtual function.

I would guess it is an error message generated by the Application (not the system), and the programmer just typed a really wierd Message that makes no sense.

But I might be wrong. And I'm speaking from a C++ perspective. It might possibly be written in some other language.

So we would need to know what language it was written in for it to make sense i suppose.
It is possible, I've done it myself. Casting a pointer to a derived class incorrectly did it (or something like that), IIRC...
I was testing my pilot AI yesterday, and after running the program (release build) for 5-10 minutes I had the very same error message. The message was not generated by the application. I'm sure this is something I can fix, but I guess calling pure virtual function shouldn't be even possible...

Edit: Ok, I guess it is possible. :)
It's possible. Something like this:

class A{public:  virtual void Foo() = 0;};class B : public A{public:  virtual void Foo();  B();  void DoStuff(A *a);};void B::Foo(){  // stuff here}B::B(){  DoStuff(this);}void B::DoStuff(A *a){  a->Foo(); // <-- BANG!}


Calling a virtual function in a constructor will generally generate a compiler error, but if you pass this to some other method, that method may call methods on a non-fully constucted object, which may result in calling a pure virtual function (A::Foo in the example above).

That's why, in general, you shouldn't pass this out of the constructor.
Quote:Original post by Dean Harding
It's possible. Something like this:

*** Source Snippet Removed ***

Calling a virtual function in a constructor will generally generate a compiler error, but if you pass this to some other method, that method may call methods on a non-fully constucted object, which may result in calling a pure virtual function (A::Foo in the example above).

That's why, in general, you shouldn't pass this out of the constructor.


Interesting.

DH: I think you mean to call that virtual method during construction of the base class, not the derived:
class A{public:  virtual void Foo() = 0;  A::A() { BaseDoStuff(this); }  void A::BaseDoStuff(A *a) { a->Foo(); }};

In void A::BaseDoStuff:
---------------------------Microsoft Visual C++ Debug Library---------------------------Debug Error!R6025- pure virtual function call(Press Retry to debug the application)---------------------------Abort   Retry   Ignore   ---------------------------

The error message you see is from the CRT provided by MSVC. Pure virtual functions (in debug mode at least) in the vtable don't actually get set to 0, they get set to __purecall(), which shows the error dialog.
From the debugger in A::BaseDoStuff:
a->__vfptr[0] = 0x004adb87 __purecall *
A quick and dirty way of finding the source of the problem is to just provide a definition for your pure virtual functions that prints an error message or stack trace or something of that sort. It's perfectly legal, and won't affect the pure virtual-ness of the functions in question. All that changes is that the nasty error goes away, replaced by one of your chosing. Then, once the problem is solved, you remove the definitions and carry on.

CM

This topic is closed to new replies.

Advertisement