Здравствуйте, BlackKhan, Вы писали:
BK>Если есть мысли о причине такой ошибки, буду очень признателен!
Штатный способ получить такую ошибку — вызвать из конструктора/деструктора абстрактный метод косвенным способом
struct Foo
{
virtual void foo() = 0;
void bar() { foo(); } // динамический вызов
Foo()
{
foo(); // статический вызов ***
bar(); // приведёт к PVFC
}
};
void Foo::foo() {} // если мы статически вызываем, значит, должны определить
// а если не вызываем (закомментируем строку ***), то в определении не нуждаемся
Причём это может быть как собственный метод, так и метод базового класса.
Нештатным способом этого можно добиться
— удачно расстреляв память
— нарушив ODR (one definition rule) — что вполне вероятно при рассогласованных DLL
Пример нарушения ODR
///////////////////
// foo.h
struct Foo
{
#ifdef FOO_THEN_BAR
virtual void foo() = 0;
virtual void bar() {}
#else
virtual void bar() {}
virtual void foo() = 0;
#endif
Foo();
};
//////////////////
// foo.cpp
#define FOO_THEN_BAR
#include "foo.h"
Foo::Foo() {} // VMT содержит: [0]=PVFC, [1]=&Foo::bar
//////////////////
// bar.h
#include "foo.h"
struct Bar : Foo
{
void buz() { bar(); }
Bar() { buz(); } // кажется, всё в порядке: динамический вызов существующего виртуального метода
};
//////////////////
// buz.cpp
//#define FOO_THEN_BAR
#include "bar.h"
struct Buz : Bar
{
void foo() {} // чтобы класс был не абстрактным
};
main()
{
Buz trahtibidoh;
// при конструировании базового подобъекта Buz мы нарвёмся на старую VMT (если RTTI выключено и Bar воспользовался VMT предка)
}