Home c++ Possible causes of the appearance of Debug Error - R6025 Pure Virtual...

Possible causes of the appearance of Debug Error – R6025 Pure Virtual Function Call

Author

Date

Category

My program completes its execution with an error:

R6025 PURE Virtual Function Call.

How is it possible to be called a purely virtual function? An abstract class instance cannot be created. If the function is virtual, then it is used later binding, i.e. The function of the object type should be called, and not by the type of reference. Those. Pure virtual function cannot be caused.
What should I do?


Answer 1, Authority 100%

In response @ant was explained how such an error may turn out. (This is a call to the virtual function, directly or indirectly, in the designer or destructor.)

Now the question is what to do.

First, try to reproduce the problem under the debugger. Microsoft advises Replace the abstract method on the Debugbreak call>Run from under the debugger and set the stoppoints on the _purecall in purevirt.c . But my problem was preliminated in Visual Studio 2015 and without these spells.

You will see in a stack exactly which abstract method you call, and searching for a stack designer or destructor of the class object, you will find an erroneous call. Remember that this may well be an indirect call, through other functions.

If you really need a virtual method in the designer, perhaps your designer does too much. Maybe it makes sense to carry out the functionality that requires a virtual function, to a separate method, and the designer is closed, and design a class through a static factory function.

Another reason for this error can serve as a function of a pointer to the already deceased object. If the object destructor has worked, then, provided that the memory occupied by the object is not covered with anyone, while attempting to call the method across the dead pointer, a purely virtual method will also be completed (this situation is similar to calling the method in the destructor), with understandable consequences. So if there is no designer / destructor in your stack, everything is much worse: you have a pointer.


Answer 2, Authority 100%

If the virtual function is used later binding, i.e. The function by type of object should be called,

This is true, but do not forget that the designer or destructor works, the current type of object works while (including for virtual call purposes) – this type, whose designer / destructor is now active.

Therefore, a classic way to call a PURE Virtual function is to call it from the constructor through the intermediary function

class c
{
Public:
 C () {foo (); }
 Virtual void pure () = 0;
 void foo () {pure (); }
};
Class D: C
{
Public:
 Virtual Void Pure () {}
};
INT MAIN ()
{
 D d;
}

Despite the fact that in the end, we create an object of class d , while working in the class of the C , there is no D exists. All virtual calls while working in the C constructor will work as if we are dealing with the class of C .

Formally To achieve the same effect, you can try to call PURE directly from C :: C () , but compilers tend to optimize such virtual calls and replace them on unpetual. At the same time, they immediately notice the catch even at the compilation stage.

Cheat the compiler in this option by making a call not directly, but through a pointer to the method, which gives us a little more compact way to achieve the same effect

class c
{
Public:
 C () {(this- & gt; * & amp; C :: PURE) (); }
 Virtual void pure () = 0;
};
Class D: C
{
Public:
 Virtual Void Pure () {}
};
INT MAIN ()
{
 D d;
}

Answer 3, Authority 33%

My problem was that I turned to the “Dead Link”, as was predicted @vladd.
Here is a simplified version of my code, with the same error:

# include & lt; iostream & gt;
using namespace std;
class A
{
public:
   virtual void f () = 0;
   virtual ~ A () {}
};
class B: public A
{
public:
   void f () {}
};
class C: public A
{
   A & amp; a;
public:
   C (A & amp; a): a (a) {}
   void f () {a.f ();}
};
class D
{
public:
   D (A & amp; a) {a.f (); }
};
int main ()
{
   C c ((B ()));
   D d (c);
   system ("pause");
}

If you change the main method like this:

int main ()
{
   B b = B ();
   C c (b);
   D d (c);
   system ("pause");
}

Then an error will not happen, because the B () object will not be deleted.

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions