__purecall проблема в VS2010 с использованием виртуальной функции - один раз метод получает чистый вызов - PullRequest
1 голос
/ 26 января 2011

У меня очень странная проблема:

Я использую один из моих базовых классов: IEventlistener (), который реализуется многими другими классами.Большую часть времени система работает.Но теперь возникла очень странная проблема.

Как только класс (CGUIService) реализует интерфейс, один метод (VGetListenerName) работает так, как ожидалось, а другой (VHandleMessage) получает чистый вызов, когда я проверяю стек вызовов и я неЯ не понимаю, почему -.- (кажется, что vtable перезаписывается или выходит за пределы ...)

Я сделал снимок экрана, чтобы вы могли видеть переменную перед вызовом VHandleMessage, что, конечно, приводит котладочное утверждение R6025 - чисто виртуальный вызов функции, потому что каким-то образом реализованный метод не введен в виртуальную таблицу IEventlistener ().

Highres: www.fantasyhaze.com/cb/Error_purecall.png www.fantasyhaze.com/cb/Error_purecall.png

Я надеюсь, что кто-то может дать мне подсказку:)

Edit1.)

Поэтому, чтобы объяснить это немного подробнее, я создал новый скриншот, который показывает тот же процесс,но теперь я включил еще 2 виртуальные функции, которые не являются чистыми и имеют реализацию (из-за нехватки времени у меня нет времени на реализацию всех встреченныхснова в каждом классе, который использует интерфейс)

Фиолетовые - новые, Красный - тот, который не работает. Оранжевый - метод, который был там прежде, и который работал и все еще работает.

С левой стороны видно, что VGetListenerName, VHandleEvent1, VHandleEvent2 работают (точка отладки + текущая позиция) и что эти 3 находятся в vtable ... но не важная (красная)

высокое разрешение: www.fantasyhaze.com/cb/Error_purecall2.png vtable problem 2

Edit2.)

РЕШЕНИЕ:

Основная проблема заключалась в том, что CGUIService наследуетиз IBase.Чтобы получить доступ к Сервису, я использовал Сервисный локатор, который хранит каждый сервис.Поэтому он выполняет static_cast в Instance Getters Service :: GetServiceInstance (), а static_cast также выполнялся для сохранения сервиса как IBase.Но IEventListener не был реализован в IBase, кроме того, Служба была возвращена в IBase без IEventListener, и vtable не был в порядке.Теперь IBase реализует IEventListener, и он работает, потому что static_cast правильно выполняет IEventListener:)

Спасибо за подсказки, ребята :)

Ответы [ 3 ]

2 голосов
/ 26 января 2011

Часто чисто виртуальный вызов вызван вызовом виртуальной функции на уже уничтоженном объекте. При уничтожении объекта каждый деструктор базового класса устанавливает указатель виртуальной таблицы на виртуальную таблицу класса. Если функция является чисто виртуальной и не имеет реализации, адрес виртуального чистого вызова помещается в виртуальную таблицу.

1 голос
/ 26 января 2011

Сложно судить по одному скриншоту, но из информации, которую вы дали, мое первое предположение будет зависать - возможно, вы пытаетесь вызвать виртуальный метод для объекта, который уже был уничтожен?Другая возможность состоит в том, что объект еще не полностью построен, но это не очень вероятно, так как для этого, скорее всего, потребуется некоторое состояние гонки в нескольких потоках.чисто виртуальный вызов функции в C ++? довольно исчерпывающе.

0 голосов
/ 26 января 2011

purecall означает, что по какой-либо причине класс, реализующий интерфейс, имеет меньше виртуальных функций, чем реализуемый им интерфейс. Это часто случается, когда:

  • вы добавляете метод в интерфейс
  • использовать новый метод в вызывающей
  • перекомпилировать вызывающую программу, но не перекомпилировать реализацию (или перекомпилировать реализацию и забыть повторно связать ее)

Так что, скорее всего, это проблема процесса сборки. Убедитесь, что вы перекомпилируете все свои данные, от которых зависит вызывающая сторона, и, если необходимо, перекомпоновайте вызывающую часть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...