У меня возникла проблема, которую я на трамвае объехал, но остался неприятный осадок. Что-то я делаю не так, как надо.
Поиск смотрел, если там и есть то, что мне надо, я не понял того, что там написано.
Ситуация такая:
class Base
{
public:
virtual void funcBase();
}
class BaseA
{
public:
virtual void funcBaseA();
}
class Impl: public Base, public BaseA
{
public:
virtual void funcBase();
void funcImpl();
}
class Store
{
public:
Base *pBase;
}
//Где-то идет объявление Store *s;
void someInit()
{
s=new Store;
s->pBase=new Impl;
/*
на самом деле классов типа Impl множество, все они наследуют
разные базовые классы, но все наследуются от Base.
Часть из них переопределяет часть методов базовых классов.
*/
}
void someUsage()
{
// В данном случае, я полностью уверен, что s->pBase указывает на объект,
// наследованный от BaseA
// BaseA *pBaseA=reinterpret_cast(s->pBase); Так не работает, выдает из глубин ассемблера обращение к нулевому указателю.
BaseA *pBaseA=dynamic_cast<BaseA *>(s->pBase);
if (pBaseA!=NULL)
pBaseA->funcBaseA(); // Вот тут проблема.
}
void someUsage_correct()
{
Impl *pImpl=dynamic_cast<Impl *>(s->pBase);
if (pImpl!=NULL)
pImpl->funcBaseA(); // так работает правильно и всегда
}
А проблема в том, что в someUsage() вызывается не BaseA::funcBaseA(), а нечто странное
.
Причем someUsage_correct() всегда работает правильно. Но проблема в том, что таких классов, как Impl (в частности наследованных и от BaseA) у меня много. Для каждого пришлось определить свою someUsage_correct(). Вот это ИМХО не правильно.
Самое смешное, что вызов как в someUsage() проходит правльно в половине случаев, а в другой половине валится на неправильный виртуальный метод.
Подскажите, в какой цепочке ДНК искать ошибку?
ЗЫ: Именно этот код я не проверял, но смысл ситуации он передает верно.
ЗЫЫ: Компилятор VC6, VC7.0, VC7.1. Пока ряд компиляторов был не таким длинным, я думал, что с моим ДНК все в порядке... Как жестоко я ошибался!
Здравствуйте, leshi, Вы писали:
[]
L>А проблема в том, что в someUsage() вызывается не BaseA::funcBaseA(), а нечто странное .
L>Причем someUsage_correct() всегда работает правильно. Но проблема в том, что таких классов, как Impl (в частности наследованных и от BaseA) у меня много. Для каждого пришлось определить свою someUsage_correct(). Вот это ИМХО не правильно.
L>Самое смешное, что вызов как в someUsage() проходит правльно в половине случаев, а в другой половине валится на неправильный виртуальный метод.
L>Подскажите, в какой цепочке ДНК искать ошибку?
В приведенном коде, кажется, ничего страшного не было. Глупый вопрос — ты не забыл включить RTTI в настройках проекта?
L>ЗЫ: Именно этот код я не проверял, но смысл ситуации он передает верно.
Ощущение, что не передает.
Здравствуйте, MaximE, Вы писали:
ME>В приведенном коде, кажется, ничего страшного не было. Глупый вопрос — ты не забыл включить RTTI в настройках проекта?
Во-во. Именно это я и не сделал.
Спасибо за исправленный ДНК